Use which: Interface or Type Alias in Typescript?
qinmu
Posted on January 4, 2023
This blog mainly discusses the key differences of interface vs type
, and share how I would use them in my daily software development routine.
Describe the shape of an object or a function signature
Both can be used to describe the shape of an object or a function signature.
However, I mostly use interface
to describe the object, and use type
to describe a function signature, as I can clearly know it’s a definition for function from arrow function
, which is impossible to realize in interface
.
interface Point {
x: number;
y: number;
}
type SetPoint = (x: number, y: number) => void;
Another scenario where I use interface is for 「Index Signatures」. For example, in dynamic generated input, we don’t know all the names of a type’s properties ahead of time, but we do know the shape of the values.
interface Input {
[index: string]: string | number;
}
Extending and Intersection Types
At first sight, extending and intersection are similar ways to combine types. However, the principle difference between the two is how conflicts are handled.
For interface
, If you declare a property with the same key, it will overrides the one in the derived interface. However, it should be compatible with the previous one, or typescript compiler will throw an error.
// This works pretty well, as it is compatible
interface Converter {
convert: (value: number) => string;
}
interface StringNumberConverter extends Converter {
convert: (value: number | string) => string;
}
// Oops...this will throw an error, as it is incompatible
interface Converter {
convert: (value: number) => string;
}
interface StringNumberConverter extends Converter {
convert: (value: string) => string;
}
For type, properties with the same key don’t have to be compatible. You can declare whatever you like.
type Converter = {
convert: (value: number) => string;
}
type StringNumberConverter = Converter & {
convert: (value: string) => string;
}
Another difference you should pay attention is the meaning they represent. When I use interface, I want it stands for the「Parent-Child」relationship. By contrast, when I use type, it only stands for 「Composition」relationship.
// 「Parent-Child」relationship. Cat derives from Animal.
interface Animal {
name: string;
}
interface Cat extends Animal {
color: string;
}
// 「Composition」relationship. Color and Size are two seperate species
type Color = {
name: string
}
type Size = {
size: 'small' | 'medium' | 'large'
}
type ColorSize = Color & Size
Class Implements
A class can implement an interface or type alias, but it can not implement Union type, as in typescript, a class can only implement an object type or intersection of object types with statically known members.
So in daily development, if this type is designed to be implemented by class, I will use interface
over type
.
type PartialPoint = { x: number; } | { y: number; };
// can not implement a union type
class SomePartialPoint implements PartialPoint {
x = 1;
y = 2;
}
More than Object Types
Unlike an interface, type alias can also be used for other types. Frequently used are such as union type and tuples.
type StringNumberPair = [string, number];
function doSomething(stringHash: [string, number]) {
const [inputString, hash] = stringHash;
console.log(inputString); // string
console.log(hash); // number
}
Declaration Merging
interface
is open, and type alias
is close within itself. An interface can be defined multiple times, and will be treated as a single interface with members of all declarations being merged.
type Bear = {
name: string;
}
// Error:Duplicate Identifier
type Bear = {
age: number;
}
// works pretty well
interface Bear {
name: string;
}
interface Bear {
age: number;
}
const b: Bear = {
name: '',
age: 0
}
Working With typeof
Type Operator
In most cases, if you want to work with typeof
type operator, choose type
over interface
.
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
/**
** type P = {
x: number;
y: number;
}
**/
Conclusion
When the next time you are confused which to use, try this cheatsheet!
Posted on January 4, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024