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>;