我是Typescript的新手,我对这个代码正确编译的原因感到有些困惑。 images
是一个字符串数组,但this.data
已分配,而images
为对象的对象。
declare type vd = {
images: Array<string>;
}
class mytest {
data: vd;
constructor() {
let obj = ['hello!', 'bye'];
this.data = { images: { ...obj } };
console.log(this.data.images);
}
}
正如预期的那样,它会打印在控制台上:
对象0:“你好!” 1:“再见”
更改常规大括号的花括号,打印以下内容:
数组(2)0:“你好!” 1:“再见”长度:2
为什么编译器在第一种情况下没有对this.data
的分配抱怨?
答案 0 :(得分:3)
在javascript和typescript中,数组是对象,所以当你将obj
变量初始化为数组时,这个无意义的操作是有效的并且允许 - 正如Aluan Haddad在评论中所说,你可以传播数组(这是一个对象)成对象:
{...obj}
要显示它产生的类型,您可以添加this pointless assignment并观看错误消息:
const r: void = { ...obj }
输入'{[n:number]:string;长度:数量; toString():string; toLocaleString():string; push(... item ...'不能分配给类型 '无效'。
看,作为传播的结果,{...obj}
的类型看起来就像一个数组,它有indexable by number signature,并且它具有数组所具有的所有属性和方法,因此,通过TypeScript结构兼容性规则,它可以分配给一个数组 - 这就是你的代码中没有错误的原因。
这与您在运行时在javascript中获得的内容不同。数组的不可枚举属性不会复制到对象,结果只有两个来自数组索引的属性 - "1"
和"2"
。
这是TypeScript类型系统的一个缺点 - 无法计算不可枚举的属性,它们被视为可枚举,就像所有其他属性一样。如果有,那么这项任务就会产生错误。