打字稿:将数组类型检查结果传递给变量

时间:2021-07-06 18:23:24

标签: javascript arrays typescript

我有一段代码,我需要在几个不同的地方知道一个变量是否是一个数组(它可以是一个数组或字符串)。如果是,我会映射数据。如果没有,我会做其他事情。

简化代码,打字稿抱怨:

function myFunc(input: unknown[] | string) {

  const isArray = Array.isArray(input);
  
  if (isArray) {
    // this line throws an error, since `map` is not a valid method for strings
    return input.map(/* do stuff here*/);
  }

  return input;

}

如果我将带有 if 语句的行更改为:

  if (Array.isArray(input))

然后打字稿似乎明白 input 实际上是一个数组。

不过,我在实际代码中的多个地方都使用了该检查,并且希望使用单个变量来提高可读性,而不是每次都执行 Array.isArray

这是怎么回事?

2 个答案:

答案 0 :(得分:2)

打字稿 4.4+

您想要做的在 Typescript 4.4 中有效(截至 2021 年 7 月 6 日未发布)

blog post detailing aliased conditions

Playground using nightly build


打字稿 4.3

在早期版本的打字稿中,您的选择更加有限。问题是打字稿不够聪明,无法理解 const isArray 是从 Array.isArray(input) 派生的。在该行之后,它只是一个布尔值,与任何其他值没有联系。

如果输入是数组,我可能会创建一个只有一个值的中间变量。这样打字稿就可以在一个变量上跟踪该类型。

类似于:

function myFunc(input: unknown[] | string) {
  const inputArray = Array.isArray(input) ? input : null

  if (inputArray) {
    return inputArray.map(str => str);
  }

  return input;
}

Playground

答案 1 :(得分:1)

output "repository_ids" { value = tomap({ for k, r in github_repository.all : k => r.repo_id }) } 是一种特殊检查,用于缩小变量类型。关于这一点有一整章:https://www.typescriptlang.org/docs/handbook/2/narrowing.html

也许您想使用一对变量并稍后在函数中使用它们。

Array.isArray

现在如果不为空就可以使用对应的变量了。但这只是将一种形式的支票转换为另一种形式,所以恕我直言,真的没有那么有用。

当然,您可以将一个变量用作任何类型,但您将失去所有 TS 优点。

const inputArray = Array.isArray(input) ? input : null;
const inputString = Array.isArray(input) ? null : input;