首页 > 解决方案 > 如果可选 prop 是 TypeScript 中的数组,如何在三元运算符中使用布尔赋值

问题描述

我需要根据可选道具是否为数组来派生对象属性。

我有这个任务:

const isRequestingMultipleDevices = Array.isArray(deviceIds);

然后这个对象:

    {
      data: isRequestingMultipleDevices
        ? deviceIds.map((deviceId) => getData(deviceId)) // Object is possibly 'undefined'
        : (deviceIds && [getData(deviceIds)]) || [], // Object is possibly 'undefined'
    };

它抱怨是因为deviceIds是可选的。但是,这很好:

    {
      data: Array.isArray(deviceIds)
        ? deviceIds.map((deviceId) => getData(deviceId))
        : (deviceIds && [getData(deviceIds)]) || [],
    };

我想使用isRequestingMultipleDevices,因为我在多个地方都需要它。

如何定义布尔值一次并在任何地方使用它?TIA

标签: reactjstypescript

解决方案


作为免责声明,我必须承认我无法引发您报告的完全相同的错误,但我相信问题是由于我们比类型检查器更了解情况。我的意思是:

在这个任务之后

const isRequestingMultipleDevices = Array.isArray(deviceIds);

我们知道以下内容:如果isRequestingMultipleDevicestrue,那么deviceIds既是定义的又Array一个。如果它是false,那么它可能是未定义的,它肯定不是一个数组。

以后,到了要用 isRequestingMultipleDevices的时候,

{
  data: isRequestingMultipleDevices
  ? deviceIds.map((deviceId) => getData(deviceId))
  : (deviceIds && [getData(deviceIds)]) || [],
};

即使我们确定在三元表达式的第一臂中deviceIds既是定义的又是 an Array,类型检查器显然无法以相同的方式缩小类型(这可能有几个原因)。因此,它会拒绝您对deviceIds.map. 拒绝的getData(deviceIds)发生出于类似的原因。

在第二种情况下,当您“内联”数组检查时,类型检查器能够推断出在第一个分支中deviceIds是 an Array,而不是Array在第二个分支中,因此它接受整个表达式。

解决此问题的一种方法是在两个呼叫站点都包含“类型断言” :deviceIds

// Assuming the device ID(s) are strings:
{
  data: isRequestingMultipleDevices
  ? (deviceIds as string[]).map((deviceId) => getData(deviceId))
  : (deviceIds && [getData(deviceIds as string)]) || [],
};

推荐阅读