“For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.” https://www.typescriptlang.org/docs/handbook/2/everyday-type...
type A = { id: number }
type B = A & { name: string }
const b: B = { id: 0, name: 'foo' }
interface X {
x(): void;
}
interface X {
y(): void;
}
class Y implements X {
x(): void {
console.log("hello");
}
y(): void {
console.log("world");
}
}
const z = new Y();
z.x();
z.y();
This is important for keeping up with API changes in browsers that may happen faster than the DefinitelyTyped project can keep up.- in error reporting: type aliases may be replaced by their definition in error reporting.
- you cannot create union types with interfaces
- legacy versions of TypeScript does not enable to create recursive type aliases such as type `List<V> = {v: V, right: List<V> | undefined }`
- interfaces with same name are merged
However the frontier between type aliases and interfaces seems more and more blur. Generally interfaces are encouraged over type aliases. I personally prefer type aliases because there are more capable and seems more elegant to me. However their poor support in error reporting makes me rely more on interfaces when possible.
A type is statically-"tagged" data from the typechecker's point of view. Even if `Foo` and `Bar` are two types with the exact same fields, the typechecker won't let you use as Foo as a Bar or vise-versa unless you've explicitly declared that Foos are Bars (via type aliasing or inheritance).
An interface declares a whole category of types that are equivalent: anything with the same "shape" as the interface will count as the interface. So you can pass objects, child objects, objects with additional fields attached, etc. to an interface input; if the thing has the fields the interface cares about, it'll accept it.
Which you want to use depends on what precisely you intend to do, but interfaces are handy in TypeScript where they may be less useful in some other languages because the underlying JavaScript is so "duck-typed" and sloppy on what it means for something to "have a type;" interfaces often model more accurately the behavior of "native" JavaScript functions (that will take an argument, assume it's an object, and just start touching some fields on it without caring whether more fields exist or not).
https://www.typescriptlang.org/docs/handbook/advanced-types....