seo*_*han 8 javascript typescript
const testArray:[number, string] = [10, 'test', 's'];
Run Code Online (Sandbox Code Playgroud)
它不起作用。
const testArray:[number, string] = [10, 'test']; // It's been edited.
testArray.push('test');
Run Code Online (Sandbox Code Playgroud)
有用。
我认为第二个代码不应该工作。
为什么第二个代码有效?这是一个错误吗?
-添加-
我一直在思考这个问题。
编译器只能在编译时捕获错误。所以编译器不会捕捉到错误。这样对吗?
jca*_*alz 11
这是一个很好的问题,我将尝试尽可能明确地重新表述它:
元组类型是一种长度已知的数组类型,其中不同的元素可能具有不同的类型。type 的
[number, string]
值保证有一个length
of2
,一个number
at 元素0
和一个string
at 元素1
。那么,为什么 TypeScript 允许您在元组类型的值上调用诸如
push()
、pop()
、shift()
、unshift()
和 之splice()
类的方法,而这些方法通常会破坏元组类型的假定保证?难道不应该阻止你这样做,就像它阻止你指定的值等[1, "two", "three"]
来[number, string]
摆在首位?
是的,这不是很好。
我不知道对此有一个很好的规范答案。我能找到的最接近的是microsoft/TypeScript#6325,它建议从元组类型中省略此类方法。该提议被拒绝,可能的理由是这将是对现有现实世界代码的重大更改。
建议的替代方案看起来像
type StrictTuple<T extends any[]> =
Omit<T, keyof (any[])> extends infer O ? { [K in keyof O]: O[K] } : never;
Run Code Online (Sandbox Code Playgroud)
它看起来不像一个数组,而更像是一组数字键属性:
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; }
Run Code Online (Sandbox Code Playgroud)
如果你真的关心这些事情,你可能想使用StrictTuple
上面的东西,但这可能比它的价值更麻烦。元组类型在 TypeScript 中无处不在,如果您使用无法分配给它们的表单,那么您将不得不跳过很多不幸的环节才能使用 TypeScript。
务实地说,我想说的是尽量不要改变元组。
这是可能的,有人可能会打开一个新的问题,引用微软/打字稿#6325问现在重新考虑这一点,元组都变得有点在这段时间更严格。看看如果push
/ pop
/etc 从元组类型中省略,具体会中断什么将是一个有趣的练习。
[删除之前的答案,因为我误解了。]
看起来这可能是与类型扩展相关的问题?您可以将元组声明为readonly
或as const
阻止推送函数在元组上工作
const testArray:readonly [number, string] = [10, 'test'] as const;
testArray.push('test') // error
Run Code Online (Sandbox Code Playgroud)
我发现这篇关于该主题的中等文章:https://blog.logrocket.com/const-assertions-are-the-killer-new-typescript-feature-b73451f35802/