Item 52: Prefer Conditional Types to Overload Signatures
May 10, 2024 ยท View on GitHub
Things to Remember
- Prefer conditional types to overloaded type signatures. By distributing over unions, conditional types allow your declarations to support union types without additional overloads.
- If the union case is implausible, consider whether your function would be clearer as two or more functions with different names.
- Consider using the single overload strategy for implementing functions declared with conditional types.
Code Samples
declare function double(x: string | number): string | number;
const num = double(12);
// ^? const num: string | number
const str = double('x');
// ^? const str: string | number
declare function double<T extends string | number>(x: T): T;
const num = double(12);
// ^? const num: 12
const str = double('x');
// ^? const str: "x"
declare function double(x: number): number;
declare function double(x: string): string;
const num = double(12);
// ^? const num: number
const str = double('x');
// ^? const str: string
function f(x: string | number) {
return double(x);
// ~ Argument of type 'string | number' is not assignable
// to parameter of type 'string'
}
declare function double<T extends string | number>(
x: T
): T extends string ? string : number;
const num = double(12);
// ^? const num: number
const str = double('x');
// ^? const str: string
function f(x: string | number) {
// ^? function f(x: string | number): string | number
return double(x); // ok
}
function double<T extends string | number>(
x: T
): T extends string ? string : number;
function double(x: string | number): string | number {
return typeof x === 'string' ? x + x : x + x;
}