Javascript TypeScript:如何在编译时声明固定大小的数组以进行类型检查
更新:这些检查用于编译时,而不是运行时。在我的示例中,失败的案例都是在编译时捕获的,我希望其他应该失败的案例也会有类似的行为 假设我正在编写一个类似表的类,其中我希望该类的所有成员都是相同长度的数组,比如:Javascript TypeScript:如何在编译时声明固定大小的数组以进行类型检查,javascript,typescript,typechecking,Javascript,Typescript,Typechecking,更新:这些检查用于编译时,而不是运行时。在我的示例中,失败的案例都是在编译时捕获的,我希望其他应该失败的案例也会有类似的行为 假设我正在编写一个类似表的类,其中我希望该类的所有成员都是相同长度的数组,比如: class MyClass { tableHead: string[3]; // expect to be a 3 element array of strings tableCells: number[3]; // expect to be a 3 element array o
class MyClass {
tableHead: string[3]; // expect to be a 3 element array of strings
tableCells: number[3]; // expect to be a 3 element array of numbers
}
到目前为止,我找到的最接近的解决方案是:
class MyClass {
tableHead: [string, string, string];
tableCells: [number, number, number];
}
let bar = new MyClass();
bar.tableHead = ['a', 'b', 'c']; // pass
bar.tableHead = ['a', 'b']; // fail
bar.tableHead = ['a', 'b', 1]; // fail
// BUT these also pass, which are expected to fail at compile time
bar.tableHead = ['a', 'b', 'c', 'd', 'e']; // pass
bar.push('d'); // pass
bar.push('e'); // pass
还有更好的主意吗 下面是一个控制内部数组长度的类的简单示例。这不是愚蠢的证明(当获得/设置你可能想考虑你是浅/深克隆等:
更新2:从3.4版开始,OP要求的内容现在完全可以通过简洁的语法()实现:
class-MyClass{
表头:只读[字符串,字符串,字符串]
tableCells:只读[数字,数字,数字]
}
更新1:从2.7版开始,现在可以使用TypeScript
我认为不可能对元组的长度进行打字检查。这是TypeScript作者对这个问题的看法
我认为你所要求的是没有必要的。假设你定义了这种类型
type StringTriplet = [string, string, string]
并定义该类型的变量:
const a: StringTriplet = ['a', 'b', 'c']
你不能从那个三元组中得到更多的变量
const [one, two, three, four] = a;
将给出一个错误,但这不符合预期:
const [one, two, three] = a;
我认为缺乏约束长度的能力成为问题的唯一情况是,例如,当您在三元组上映射时
const result = a.map(/* some pure function */)
并且期望result
有3个元素,而实际上它可以有3个以上的元素。但是,在这种情况下,您将a
视为一个集合,而不是元组,因此对于元组语法来说,这不是一个正确的用例。From,以编程方式,具有动态长度:
type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & { length: TLength };
type Tuple9<T> = Tuple<T, 9>;
type Tuple=[TItem,…TItem[]]和{length:tllength};
类型Tuple9=Tuple;
您应该将您的成员数据包装在访问函数中。然后,这些函数可以检查请求添加到数组中的参数数量和/或数据长度。您的意思是getter
和setter
?是的。将它们设为私有,并提供方法来控制从列表中推送或删除的内容。这样您就有了total控制it@iberbeu如果我理解正确,这提供了运行时检查,对吗?编译时如何?就像C/C++中的方式。目前不可能,但有一个建议:感谢您的回答,但正如您在问题下的讨论中所看到的,我打算在编译时而不是运行时执行此检查。我正在更新t他提出这个问题是为了避免将来的混淆。回答得好。我喜欢你加入Hejlsberg的评论,这有助于理解背景。如果这个硬编码的9需要是动态的呢。换句话说,给定两个元组,我希望第二个元组与第一个元组一样长。
type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & { length: TLength };
type Tuple9<T> = Tuple<T, 9>;