const testArray:[number, string] = [10, 'test', 's'];
它不起作用。const testArray:[number, string] = [10, 'test']; // It's been edited.
testArray.push('test');
有用。我认为第二个代码不应该起作用。
为什么第二个代码有效?它是一个错误吗?
-添加-
我一直在思考这个问题。
编译器只能在编译时捕获错误。所以编译器不会捕捉到错误。这样对吗?
最佳答案
这是一个很好的问题,我将尝试尽可能明确地改写它:
Tuple types are a type of array of known length and where the different elements may have different types. A value of type
[number, string]
is guaranteed to have alength
of2
, with anumber
at element0
and astring
at element1
.Why then, does TypeScript allow you to call methods like
push()
,pop()
,shift()
,unshift()
, andsplice()
on values of tuple types, when such methods generally destroy the supposed guarantees of tuple types? Shouldn't it stop you from doing that, just like it stops you from assigning a value like[1, "two", "three"]
to[number, string]
in the first place?
是的,这不是很好。
我不知道对此有一个很好的规范答案。我能找到的最接近的是 microsoft/TypeScript#6325 ,它建议从元组类型中省略这些方法。这个提议被拒绝了,理由是它可能是 a breaking change对于现有的真实世界代码。
建议的替代方案看起来像
type StrictTuple<T extends any[]> =
Omit<T, keyof (any[])> extends infer O ? { [K in keyof O]: O[K] } : never;
它看起来不像一个数组,而更像是一组数字键属性:const x: StrictTuple<[number, string]> = [1, ""] // {0: number; 1: string }
x[1] = "okay";
x[0] = 123;
x.push(123); // error!
//~~~~ Property 'push' does not exist on type { 0: number; 1: string; }
如果你真的很在意这些事情,你可能想要使用类似 StrictTuple
的东西。上面,但它可能比它的值(value)更麻烦。元组类型在 TypeScript 中无处不在,如果您使用不可分配给它们的形式,那么您将不得不跳过许多不幸的箍来使用 TypeScript。务实地说,我想说尽量不要改变元组。
有一些引用 microsoft/TypeScript#6325 的新问题要求重新考虑这一点,因为在此期间元组变得更加严格。见 microsoft/TypeScript#40316和 microsoft/TypeScript#48465 ,它们是开放的,但不是很受欢迎。看看如果
push
会破坏什么,这将是一个有趣的练习。/pop
元组类型中省略了/etc。Playground link to code
关于javascript - Typescript数组推送方法无法捕获数组的元组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64069552/