Texto tipográfico atribuindo uma interface ou um tipo a um Record <string, string>

Nov 23 2020

Depois de ler esta pergunta ou este artigo , ainda estou um pouco confuso sobre as diferenças sutis entre um interfacee um type.

Neste exemplo, meu objetivo é atribuir um objeto simples a um Record<string, string>tipo mais amplo :

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

Tente

A atribuição é possível ao declarar meu objeto com um type, mas não ao declarar um semelhante com um interface. Ele diz que a assinatura do índice está faltando, mas para meu (limitado) conhecimento sobre assinaturas de índice, nenhuma delas MyTypee MyInterfacena verdade tenho uma.

Qual é a razão pela qual a última linha não compila enquanto a anterior sim?

Respostas

2 ddprrt Nov 23 2020 at 21:51

Record<string, string>é o mesmo que { [key: string]: string }. A atribuição de um subconjunto a este tipo de assinatura de índice só é possível se todas as propriedades desse tipo forem conhecidas e puderem ser verificadas em relação a esta assinatura de índice. No seu caso, tudo de exampleTypeé atribuível a Record<string, string>. Isso só pode ser verificado para tipos literais de objeto, pois os tipos literais de objeto não podem ser alterados depois de declarados. Assim, a assinatura do índice é conhecida.

Fonte: https://github.com/microsoft/TypeScript/pull/7029

Em contraste, as interfaces não são finais no momento em que você as declara. Sempre existe a possibilidade de adicionar novos membros à mesma interface devido à fusão de declarações.