Typescript推断的数组解构类型冲突



嗨,我是typescript的新手,不确定如何强制数组解构的类型,使其与函数(React FC(的输入类型相匹配。

在这种情况下,这意味着解构的参数仅为字符串类型,而不是字符串|未定义。(因为如果道具未定义,我希望typescript显示一个错误(。

这里有一个代码沙盒,它运行代码,语法突出显示类型错误。

以下是一些演示问题的代码:

const data = [
['a1', 'b1', 'c1'],
['a2', 'b2', 'c2'],
]
//react components
interface showItemProps {a: string, b: string, c:string}
function ShowItem({a, b, c}:showItemProps){
return <div>{`${a} ${b} ${c}`}</div>
}
function ShowAllItems(){
return <div>
{data.map(([a,b,c], i) => <ShowItem a={a} b={b} c={c} key={i}/> )}
</div>
}

这是导致的类型错误:

(property) showItemProps.a: string
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
tst1.tsx(8, 26): The expected type comes from property 'a' which is declared here on type 'IntrinsicAttributes & showItemProps'

我试着在某些地方明确地添加类型,但似乎并不能解决问题,也找不到任何类似的问题,任何帮助都将不胜感激:(。

有几个选项:

  1. 使用as const关键字让TypeScript推断更严格的类型:
const data = [
['a1', 'b1', 'c1'],
['a2', 'b2', 'c2'],
] // Has type string[][]
const constData = [
['a1', 'b1', 'c1'],
['a2', 'b2', 'c2'],
] as const // has type [['a1', 'b1', 'c1'], ['a2', 'b2', 'c2']]

这解决了这个问题,因为现在编译器知道外部数组的每个元素都是一个有三个元素的数组,这意味着abc永远不会被定义。此选项的缺点:它实际上只适用于静态数据,因为数组将通过as const关键字只读。

  1. Nuke;有问题的";配置:

编译器认为数组中的值未定义,因为您在tsconfig.json中指定了"noUncheckedIndexedAccess": true。这意味着数组中每一个未被类型化为元组的元素(稍后会详细介绍(都可能被认为是未定义的。从tsconfig中删除该条目或将值设置为false也将禁用该行为。

  1. 使用显式元组类型帮助编译器:

元组类型定义了数组的结构:CCD_;这个数组正好包含三个字符串元素&";,CCD_ 8表示";这个数组在前三个位置包含三个字符串元素,然后在它后面包含一些其他东西。在这两种情况下,第2点提到的规则都会理解数组中确实有三个字符串,当你尝试使用它们时不会打扰你。你可以通过以下两种方式之一来利用它:

3.1以这种方式键入您的数据:

const data: [string, string, string][] = [
['a1', 'b1', 'c1'],
['a2', 'b2', 'c2'],
];

现在,所有元素都保证是三个字符串(与as const关键字不同,数组仍然是可变的(。

3.2明确的类型保护和检查

<div>
{data
.filter((x): x is [string, string, string] => x.length >= 3)
.map(([a, b, c], i) => (
<ShowItem a={a} b={b} c={c} key={i} />
))
}
</div>

如果你不知道你的数据有多长,你可以在混合中添加一个带有typeguard的过滤器。filter函数的返回类型为x is [string, string, string],这意味着如果谓词返回true,typescript可以假设参数x是函数中给定的类型。结果与3.1中的结果相同,但实际上在运行时检查是否存在至少3个元素。

最新更新