In TypeScript, both ‘type‘ and ‘interface‘ can be used to define a function type, but they have some differences in how they support features like declaration merging, readability, and the ability to extend or implement other types. Let’s dive into these differences with examples.
1. Declaration Merging:
One significant difference between ‘type‘ and ‘interface‘ is that multiple interfaces with the same name automatically merge, while types with the same name will throw an error.
For example:
interface FooFn {
(x: number): number;
}
interface FooFn {
(y: string): string;
}
const foo: FooFn = (arg: number | string) => {
// Dummy implementation
return typeof arg === "number" ? arg * 2 : arg.toUpperCase();
};
Now, using ‘type‘:
type FooFn = (x: number) => number;
type FooFn = (y: string) => string; // Error: Duplicate identifier 'FooFn'.
2. Implementing and Extending:
Interfaces can ‘extend‘ other interfaces, and classes can ‘implement‘ them. This feature does not exist in ‘type‘ directly, although you can use intersection types to achieve a similar purpose.
For example:
interface BaseFn {
(x: number): number;
}
interface DerivedFn extends BaseFn {
(x: number, y: number): number;
}
class MyFunction implements DerivedFn {
// Implementation
}
Now, using ‘type‘:
type BaseFn = (x: number) => number;
type DerivedFn = BaseFn & ((x: number, y: number) => number);
class MyFunction {
// Implementation
}
3. Readability:
When defining a simple function type, using ‘type‘ can be more concise and readable compared to ‘interface‘.
For example:
type SimpleFn = (x: number) => number;
interface SimpleFn {
(x: number): number;
}
Both ‘SimpleFn‘ definitions are equivalent, but the ‘type‘ version is shorter and more straightforward.
In conclusion, if you need declaration merging, extending, or implementing other types, ‘interface‘ is the way to go. However, if you want a simple function type and more concise syntax, ‘type‘ can be a better choice.