在阅读this question或本文之后,我仍然对interface
和type
之间的细微差别感到有点困惑。
在这个例子中,我的目标是将一个简单的对象分配给一个更广泛的Record<string, string>
类型:
interface MyInterface {
foobar: string;
}
type MyType = {
foobar: string;
}
const exampleInterface: MyInterface = { foobar: 'hello world' };
const exampleType: MyType = { foobar: 'hello world' };
let record: Record<string, string> = {};
record = exampleType; // Compiles
record = exampleInterface; // Index signature is missing
试试看
当用type
声明我的对象时,赋值是可能的,但当用interface
声明类似的对象时,赋值就不可能了。它说索引签名丢失了,但根据我对索引签名的(有限的)理解,MyType
和MyInterface
实际上都没有索引签名。
为什么最后一行不能编译,而前一行可以编译?
2条答案
按热度按时间vsmadaxz1#
Record<string, string>
与{ [key: string]: string }
相同。允许将子集分配给此 * 索引签名类型 * 只有在该类型的所有属性都已知并且可以针对此索引签名进行检查时才可能。在您的情况下,来自exampleType
的所有内容都可以分配给Record<string, string>
。这只能检查对象文字类型,as对象文字类型一旦声明就不能改变。因此,索引签名是已知的。来源:https://github.com/microsoft/TypeScript/pull/7029
相反,接口在你声明的那一刻并不是最终的。由于声明合并,总是有可能向同一个接口添加新成员。
o3imoua42#
有一种解决方法,即提供一个与您要分配的接口兼容的中间类型: