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?
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 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.
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 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 .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With