【发布时间】:2017-08-04 01:06:13
【问题描述】:
在 JavaScript 中,普通的旧对象可能会受到各种滥用。例如你可以写:
var obj = {};
var func = new Function() {};
obj[func] = 5; // totally fine
obj[func]; // returns 5
通过一些创意,您可以编写一个泛型类SimpleSet<T>,它可能使用一个对象作为其在 JavaScript 或 TypeScript 中的后备存储。一种直接的方法可能涉及编写如下内容:
public add(val: T) {
this._dict[val] = val;
}
这在 TypeScript 中不起作用。 为什么?更宽松的add 版本有效,请参阅add2 和add3。
class SimpleSet<T> {
_dict: Object;
constructor() {
}
// error:
public add(val: T) {
this._dict[val] = val;
}
// no error:
public add2(val: T) {
this._dict[val as any] = val;
}
// no error:
public add3(val: any) {
this._dict[val] = val;
}
}
使用add,出现两个错误:
类型“T”不能分配给类型“Object[T]”。
类型“T”不能用于索引类型“对象”。
为什么?
【问题讨论】:
-
您的函数创建语法错误,但是您是否意识到将函数设置为 JS 对象的键会将函数强制转换为字符串,从而创建类似于这样的键:
"function (){}"?跨度> -
var obj = {}; var key1 = {prop1:'val1'}; var key2 = {prop2:'val2'}; obj[key1] = "hello"; console.log(Object.keys(obj));将记录["[object Object]"]。记录obj[key2]将显示“hello”,因为两个对象的toString()相同。 -
你在一些不起作用的事情上已经走了很远......
-
我并没有试图在这里制作一个可行的集合(这在 JS 中也很疯狂),而是试图找出允许
any与禁止Object的规则类型。我现在看到我错误地认为any的意思是“允许所有类型”,而不是“选择退出类型检查”。
标签: javascript generics typescript