981377660LMT / ts

ts学习
6 stars 1 forks source link

在“IParam”类型中缺少“string”类型的索引签名 - TS中的type、interface关于索引签名的区别 #424

Open 981377660LMT opened 8 months ago

981377660LMT commented 8 months ago

https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript#answer-64971386

That's the biggest practical difference imho - an interface will never be assignable to Record<string, unknown> 一个接口不能赋值给一个需要Record<string,any>的变量。

为什么? 因为 接口可合并,即interface定义类型的状态都不是最终态

例如:

增加属性前:interface valType { a: number }
增加属性后:interface valType { a: number; b: string; c: boolean; }

可以看出,增加属性后的类型,已经跟类型{ [key: string ]: number; a: number }对不齐了,因此必须要加上索引签名,立个“规矩”,规定以后新增的属性必须满足索引签名的条件时才能够加入,否则不可加入。

这种情况下必须用type。

981377660LMT commented 8 months ago

https://juejin.cn/post/7057471253279408135

981377660LMT commented 8 months ago

因interface可声明合并,声明的变量类型可新增属性,不是终态,所以在给有索引签名的类型赋值时,需增加索引签名限定新增属性的类型。而使用type声明的变量类型不可新增属性,已是最终状态,只要其属性符合被赋值变量的类型,就可以直接赋值,不会报错。

没有办法时:

  1. 如果Record报错,就用object代替,或者用 type 代替 interface。