打字稿类型强制执行

时间:2018-02-07 01:27:55

标签: typescript

我是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的分配抱怨?

1 个答案:

答案 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类型系统的一个缺点 - 无法计算不可枚举的属性,它们被视为可枚举,就像所有其他属性一样。如果有,那么这项任务就会产生错误。