如何在不同类型之间使用TypeScript中的Array.Includes

fumotvh3  于 2023-06-30  发布在  TypeScript
关注(0)|答案(3)|浏览(245)

如果Array.includes()结果类型是输入对象类型更紧密类型,则会出错。这个怎么办?这是一个例子。
index.d.ts

type OddNumberType = 1|3|5|7|9
type AllNumberType = OddNumberType|0|1|...|9

businessLogic.ts

let targetNumber:AllNumberType = parseInt(Math.random*10)
const oddArray:OddNumberType[] = [1,3,5,7,9]
let resultNumber:OddNumberType = 1;

if(oddArray.includes(targetNumber)){
 resultNumber = targetNumber
}

TS问题

Type 'AllNumberType' is not assignable to type 'OddNumberType'.
  Type 2 is not assignable to type 'OddNumberType'.ts(2322)
xurqigkl

xurqigkl1#

看起来你想使用oddArray.includes,就好像它是一个类型保护器,它接受一个任意的数字作为它的参数,如果它返回true,那么Typescript应该将参数的类型缩小为OddNumberType
Array.includes方法没有像这样声明为类型保护,也不应该是:如果类型保护返回false,这应该意味着参数不是它保护的类型,但通常如果某个类型T[]的数组不包含元素,这并不意味着该元素不是T类型。你的数组有一些特殊之处,这使得它的includes方法在这个特定的情况下成为一个明智的类型保护--它不仅仅是一个OddNumberType值的数组,它是一个 everyOddNumberType值的数组。
因此,我们可以声明一个类型ArrayOfEveryOddNumber,它与OddNumberType[]相同,但它的includes方法是一个类型保护:

type ArrayOfEveryOddNumber = OddNumberType[] & {
    includes(arg: AllNumberType): arg is OddNumberType
}
const oddArray = [1, 3, 5, 7, 9] as ArrayOfEveryOddNumber;

注意,还需要类型Assertas ArrayOfEveryOddNumber
Playground链接

vltsax25

vltsax252#

for (const oddNum of oddArray) {
    if (oddNum === targetNumber) {
      resultNumber = oddNum;
      break;
    }
  }

for循环是答案。array.find或array.includes不能在不同的in&out类型之间使用?

cbwuti44

cbwuti443#

快速解决方法是添加as

const myArray: string[] = ["1", "2", "3"]
const value: number|string = ["1", 2, 3].random() 

myArray.includes(value as string)

如果includes的参数接受包含数组类型的任何类型,则会更好。

相关问题