インターフェイスまたはタイプをRecord <string、string>に割り当てるTypescript
読んだ後、この質問や、この記事を、私はまだ少しの間の微妙な違いについて混乱している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
。
前の行がコンパイルするのに最後の行がコンパイルされない理由は何ですか?
回答
Record<string, string>
と同じ{ [key: string]: string }
です。サブセットをこのインデックスシグニチャタイプに割り当てることができるのは、そのタイプのすべてのプロパティが既知であり、このインデックスシグニチャと照合できる場合のみです。あなたの場合、からのすべてexampleType
がに割り当て可能Record<string, string>
です。オブジェクトリテラルタイプは宣言すると変更できないため、これはオブジェクトリテラルタイプについてのみチェックできます。したがって、インデックス署名は既知です。
ソース: https://github.com/microsoft/TypeScript/pull/7029
対照的に、インターフェースは、宣言した瞬間に最終的なものではありません。宣言のマージにより、同じインターフェイスに新しいメンバーが追加される可能性は常にあります。