Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

After reading this question or this article, I'm still a bit confused about the subtle differences between an interface and a type.

In this example, my goal is to assign a simple object to a broader Record<string, string> type:

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. It says that the index signature is missing, but to my (limited) understanding of index signatures, none of MyType and MyInterface actually have one.

What is the reason why the last line does not compile whereas the previous one does?

like image 462
Raffaele Canale Avatar asked Nov 23 '20 14:11

Raffaele Canale


People also ask

What is record type in TypeScript?

A Record is a utility type - that means it is a type especially defined by TypeScript to help with a certain problem. You can learn more about utility types here.

When should you use type class or interface in TypeScript?

When should we use classes and interfaces? If you want to create and pass a type-checked class object, you should use TypeScript classes. If you need to work without creating an object, an interface is best for you.

What is difference between type and interface in TypeScript?

The typescript type supports only the data types and not the use of an object. The typescript interface supports the use of the object. Type keyword when used for declaring two different types where the variable names declared are the same then the typescript compiler will throw an error.

What is ?: In TypeScript?

What does ?: mean in TypeScript? Using a question mark followed by a colon ( ?: ) means a property is optional. That said, a property can either have a value based on the type defined or its value can be undefined .


1 Answers

Record<string, string> is the same as { [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>. 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

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.

like image 166
ddprrt Avatar answered Sep 21 '22 14:09

ddprrt