Typographie attribuant une interface ou un type à un Record <string, string>
Après avoir lu cette question ou cet article , je suis encore un peu confus sur les différences subtiles entre un interface
et un type
.
Dans cet exemple, mon objectif est d'assigner un objet simple à un Record<string, string>
type plus large :
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
Essayez-le
L'affectation est possible lors de la déclaration de mon objet avec a type
, mais pas lors de la déclaration d'un objet similaire avec un interface
. Il dit que la signature d'index est manquante, mais à ma compréhension (limitée) des signatures d'index, aucune MyType
et n'en MyInterface
possède une.
Quelle est la raison pour laquelle la dernière ligne ne compile pas alors que la précédente le fait?
Réponses
Record<string, string>
est le même que { [key: string]: string }
. L'affectation d'un sous-ensemble à ce type de signature d'index n'est possible que si toutes les propriétés de ce type sont connues et peuvent être vérifiées par rapport à cette signature d'index. Dans votre cas, tout exampleType
est attribuable à Record<string, string>
. Cela ne peut être vérifié que pour les types littéraux d'objet, car les types littéraux d'objet ne peuvent pas être modifiés une fois que vous les avez déclarés. Ainsi, la signature d'index est connue.
La source: https://github.com/microsoft/TypeScript/pull/7029
En revanche, les interfaces ne sont pas définitives au moment où vous les déclarez. Il y a toujours la possibilité d'ajouter de nouveaux membres à la même interface en raison de la fusion des déclarations.