为什么Typescript会忽略超出已知大小的元组内容?

时间:2018-01-05 23:03:18

标签: typescript types tuples

有没有让Typescript不允许这个?

type TwoItemTuple  = [string, string];
const uh: TwoItemTuple = ['a', 'b', 'a']

如果没有,背后的原因是什么?

2 个答案:

答案 0 :(得分:3)

您也可以尝试这样的事情:

type OnlyTwo<T1, T2 = T1> = [T1, T2] & {
    0: T1;
    1: T2;
    2?: never;
}

var x: OnlyTwo<number> = [1, 1]; // Okay;
var y: OnlyTwo<number> = [1, 1, 1]; // Error
var z: OnlyTwo<number> = [1, 1, undefined]; // Error
var o: OnlyTwo<number> = [1]; // Error
var b: OnlyTwo<number> = [1, 1, 1, 1] // Error

var s1: OnlyTwo<number, string> = [1, "a"] // Okay
var s1: OnlyTwo<number, string> = [1, "a", 1] // Error

据我所知,对于那种类型,唯一能分配给它的是一个数组文字,其中只有两个正确类型的项目。

一个问题是您可以使用pushpop来修改这些数组,这会将实际值转换为不再符合该类型的值。请谨慎使用。

答案 1 :(得分:2)

根据元组的TypeScript文档:https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple(强调我的)

  

元组类型允许您表示一个数组,其中固定数量的元素的类型已知 ...

     

访问具有已知索引的元素时,会检索到正确的类型...

     

在访问已知索引集之外的元素时,会使用联合类型...

不幸的是,对于您的情况,无法为元组类型强制执行最大数量的元素,但是至少有两个string元素,并且任何其他元素必须是字符串。即使uh.push(nonString)也行不通。

如果你绝对需要强制元组的元素数量,你可以考虑使用Object类型,例如type TwoItemTuple = { prop0: string, prop1: string },尽管具有数组的属性。 / p>

请注意,使用括号表示法时,TypeScript不强制使用类型安全性;即使uh['foo']也可以。