インターフェイスまたはタイプをRecord <string、string>に割り当てるTypescript

Nov 23 2020

読んだ後、この質問や、この記事を、私はまだ少しの間の微妙な違いについて混乱しているinterfacetype

この例では、私の目標は、単純なオブジェクトをより広い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 ddprrt Nov 23 2020 at 21:51

Record<string, string>と同じ{ [key: string]: string }です。サブセットをこのインデックスシグニチャタイプに割り当てることができるのは、そのタイプのすべてのプロパティが既知であり、このインデックスシグニチャと照合できる場合のみです。あなたの場合、からのすべてexampleTypeがに割り当て可能Record<string, string>です。オブジェクトリテラルタイプは宣言すると変更できないため、これはオブジェクトリテラルタイプについてのみチェックできます。したがって、インデックス署名は既知です。

ソース: https://github.com/microsoft/TypeScript/pull/7029

対照的に、インターフェースは、宣言した瞬間に最終的なものではありません。宣言のマージにより、同じインターフェイスに新しいメンバーが追加される可能性は常にあります。