简体   繁体   English

为 Record 分配接口或类型的打字稿<string, string>

[英]Typescript assigning an interface or a type to a Record<string, string>

After reading this question or this article , I'm still a bit confused about the subtle differences between an interface and a type .在阅读了这个问题这篇文章后,我仍然对interfacetype之间的细微差别感到有些困惑。

In this example, my goal is to assign a simple object to a broader Record<string, string> 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

Try it 尝试一下

The assignment is possible when declaring my object with a type , but not when declaring a similar one with an interface .使用type声明对象时可以进行赋值,但在使用interface声明类似对象时则不能进行赋值。 It says that the index signature is missing, but to my (limited) understanding of index signatures, none of MyType and MyInterface actually have one.它说缺少索引签名,但就我对索引签名的(有限)理解而言,实际上MyTypeMyInterface都没有。

What is the reason why the last line does not compile whereas the previous one does?最后一行没有编译而前一行编译的原因是什么?

Record<string, string> is the same as { [key: string]: string } . Record<string, string>{ [key: string]: string } A subset is allowed to be assigned to this index signature type is only possible if all properties of that type are known and can be checked against this index signature.只有当该类型的所有属性都已知并且可以针对该索引签名进行检查时,才允许将子集分配给该索引签名类型 In your case, everything from exampleType is assignable to Record<string, string> .在您的情况下, exampleType所有内容都可以分配给Record<string, string> This can be only checked for object literal types, as object literal types can't be changed once you declared them.这只能检查对象文字类型,因为一旦声明对象文字类型就无法更改。 Thus, the index signature is known.因此,索引签名是已知的。

Source: https://github.com/microsoft/TypeScript/pull/7029来源: https : //github.com/microsoft/TypeScript/pull/7029

In contrast, interfaces are not final the moment you declare them.相比之下,接口在您声明它们的那一刻就不是最终的。 There is always the possibility of adding new members to the same interface due to declaration merging.由于声明合并,总是有可能向同一接口添加新成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM