打字稿:如何在编译时
更新声明固定大小的阵列,用于类型检查:这些检查意味着编译时,而不是在运行时。在我的例子中,失败的案例都在编译时被捕获,并且我预计其他应该失败个案也会发生类似的行为。打字稿:如何在编译时
想我正在写一个类似表格类,我想在类的所有成员都成为相同长度的阵列,喜欢的东西:
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
有没有更好的办法?
下面是控制其内部数组长度的一个简单示例。它不是傻瓜证明(获得时/设置你可能要考虑是否是浅/深克隆等:
https://jsfiddle.net/904d9jhc/
class ControlledArray {
constructor(num) {
this.a = Array(num).fill(0); // Creates new array and fills it with zeros
}
set(arr) {
if (!(arr instanceof Array) || arr.length != this.a.length) {
return false;
}
this.a = arr.slice();
return true;
}
get() {
return this.a.slice();
}
}
$(document).ready(function($) {
var m = new ControlledArray(3);
alert(m.set('vera')); // fail
alert(m.set(['vera', 'chuck', 'dave'])); // pass
alert(m.get()); // gets copy of controlled array
});
感谢您的答案,但正如您在问题讨论中所看到的,我打算执行此操作在**编译时检查**,而不是运行时。我正在更新这个问题以避免将来的混淆。 – benjaminz
我不认为这是可能的类型检查一个元组的长度。Here的打字稿的作者对这个问题的看法。
我要说什么你问的是没有必要的。假设你确定这种类型
type StringTriplet = [string, string, string]
,并定义类型的变量:
const a: StringTriplet = ['a', 'b', 'c']
你不能得到更多的变量指出,三重例如
const [one, two, three, four] = a;
会给而这并不如预期的错误:
const [one, two, three] = a;
,我认为缺乏约束长度能力成为唯一形势的一个问题是如当你map
在三重
const result = a.map(/* some pure function */)
并期待result
有3个元素的时候,其实它可以有超过3个。但是,在这种情况下,你是治疗a
作为一个集合,而不是反正一个元组,这样的不是元组语法的正确用例。
很好的答案。我喜欢你包括Hejlsberg的评论,有助于理解背景。 – sleske
你应该将你的成员数据包装在访问函数中。然后这些可以检查要求添加到阵列的参数数量和/或数据长度。 –
你的意思是'getter'和'setter'? – benjaminz
是的。使它们保持私密并提供方法来控制正在推送或从列表中删除的内容。那么你将有完全的控制 – iberbeu