Read the original from TypeScript handbook
Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
Extending an interface
interface Animal {
name: string;
}
interface Bear extends Animal {
honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;Adding new fields to an existing interface (declaration merging)
interface Window {
title: string;
}
interface Window {
ts: TypeScriptAPI;
}
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});Extending a type via intersections
type Animal = {
name: string;
}
type Bear = Animal & {
honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;A type cannot be changed after being created
type Window = {
title: string;
}
type Window = {
ts: TypeScriptAPI;
} // Error: Duplicate identifier 'Window'.But type can do union, especially discriminated union
type NetworkLoadingState = {
state: "loading";
};
type NetworkFailedState = {
state: "failed";
code: number;
};
type NetworkSuccessState = {
state: "success";
response: {
title: string;
duration: number;
summary: string;
};
};
// Create a type which represents only one of the above types
// but you aren't sure which it is yet.
type NetworkState =
| NetworkLoadingState
| NetworkFailedState
| NetworkSuccessState;microsoft/Typescript/wiki/Performance#preferring-interfaces-over-intersections
Much of the time, a simple type alias to an object type acts very similarly to an interface.
interface Foo {
prop: string;
}
type Bar = { prop: string };However, and as soon as you need to compose two or more types, you have the option of extending those types with an interface, or intersecting them in a type alias, and that’s when the differences start to matter.
Interfaces create a single flat object type that detects property conflicts, which are usually important to resolve! Intersections on the other hand just recursively merge properties, and in some cases produce never. Interfaces also display consistently better, whereas type aliases to intersections can’t be displayed in part of other intersections. Type relationships between interfaces are also cached, as opposed to intersection types as a whole. A final noteworthy difference is that when checking against a target intersection type, every constituent is checked before checking against the “effective”/“flattened” type.
For this reason, extending types with interfaces/extends is suggested over creating intersection types.
- type Foo = Bar & Baz & {
- someProp: string;
- }
+ interface Foo extends Bar, Baz {
+ someProp: string;
+ }interface vs. type doesn’t matter. They’re almost interchangeable. Interfaces can be merged, types are needed for unions, but those are basically the only differences, so just pick one and go with it. - reddit -