Typescript 为记录分配接口或类型的类型脚本<;字符串,字符串>;

Typescript 为记录分配接口或类型的类型脚本<;字符串,字符串>;,typescript,Typescript,在阅读了or之后,我仍然对接口和类型之间的细微差别感到困惑 在本例中,我的目标是将一个简单对象分配给更广泛的记录类型: 接口MyInterface{ foobar:字符串; } 类型MyType={ foobar:字符串; } const exampleInterface:MyInterface={foobar:'hello world'}; const exampleType:MyType={foobar:'hello world'}; let record:record={}; 记录=示例类

在阅读了or之后,我仍然对
接口
类型
之间的细微差别感到困惑

在本例中,我的目标是将一个简单对象分配给更广泛的
记录
类型:

接口MyInterface{
foobar:字符串;
}
类型MyType={
foobar:字符串;
}
const exampleInterface:MyInterface={foobar:'hello world'};
const exampleType:MyType={foobar:'hello world'};
let record:record={};
记录=示例类型;//汇编
记录=示例接口;//缺少索引签名

当使用
类型
声明我的对象时,可以进行赋值,但当使用
接口
声明类似对象时,则不能进行赋值。它说索引签名缺失,但就我对索引签名的(有限的)理解而言,
MyType
MyInterface
实际上都没有索引签名

最后一行不编译而前一行编译的原因是什么?

记录与
{[key:string]:string}
相同。只有当该类型的所有属性都已知并且可以对照该索引签名进行检查时,才允许将子集分配给该索引签名类型。在您的情况下,从
exampleType
Record
的所有内容都是可分配的。这只能针对对象文字类型进行检查,因为一旦声明了对象文字类型,就无法更改它们。因此,索引签名是已知的

资料来源:


相反,接口在声明时并不是最终的。由于声明合并,总是有可能向同一接口添加新成员。

有趣。我没有意识到这一点,但这是有道理的。类型
{foobar:string}
是您可以接收的内容的下限。它的基本意思是“至少有一个键
foobar
的任何对象”。显然,将其制成一种类型保留了这一含义。但是,对于接口,语义是不同的,它可能没有任何其他键。这有点奇怪,因为两个变量都不接受添加名为
hello
的新键。因此,它们的可分配性不同。