-
Using Overloads in TypeScript to Narrow a Function’s Return Type
-
What are function overloads in TypeScript?
-
How to narrow a TS function’s return type based on its parameters’ types?
-
How to narrow a TypeScript function’s return type based on its parameter types?
-
Your function’s return type is a union of multiple possibilities, but depending on the parameters passed in, you want to narrow those possibilities to one so consumers know exactly what type their receiving
-
If TS isn’t figuring out those conditional types on its own, you need to overload your function definition for each combination of parameter types + return types
-
Above your implementation, repeat the signature with as many specific combos of param/return types as there are
- add code examples
- StackOverflow example:
function makeBinsFromArray<T>(
value: T[],
binSize: number,
fillLast: true
): (T | undefined)[][]
function makeBinsFromArray<T>(
value: T[],
binSize: number,
fillLast?: false
): T[][]
function makeBinsFromArray<T>(
value: T[],
binSize: number,
fillLast?: boolean
): (T | (T | undefined))[][] {
/// implementation
}
const resultA = makeBinsFromArray([1, 2, 3], 2, true);
// (T | undefined)[][]
const resultB = makeBinsFromArray([1, 2, 3], 2);
// T[][];
-
base more on
useQueryParams.ts
example- one param in an options object is simpler than 3 params
-
Those overload signatures should have no implementation (no body); just a signature
-
Your goal is to tell TS exactly what the function’s return type should be in each param type scenario
-
Then, after those specific overloads comes your original function with its broader param and return types encompassing all the possibilities + the implementation of the function body
-
Rules:
- Same number of arguments
- You can define as many overload declarations as you like, but only one overload can implement the function
- The function signature of the implementation function must be a union of all the other function declaration types
- You must define all of the function declarations with the
function
keyword (rather thanlet
orconst
); if you don’t, you’ll wonder why TS is giving you aduplicate identifier
error while you’re using a supported TS feature
Note: Functions with same name and different number of arguments are not understood by TS as overloaded functions.
How to make ESLint happy
- use actual error term and link to the docs
- show the ignore comment options
/* eslint-disable no-redeclare */
Further reading
- Function Overloads | TypeScript Docs
- TypeScript — function overloading | Rachita Bansal
- Can I change the return type based on a parameter | StackOverflow
- Typescript return type depending on parameter | StackOverflow
- Is it possible to conditionally narrow a return type based on a parameter property that’s not passed in? | StackOverflow
- Use conditional type to narrow return type of function with a union-typed argument — TypeScript GitHub issue discussion concluding it isn’t possible for TS to automatically resolve a conditional type based on a parameter type
Inbox
- Reference this Reddit question (or post this article there once published?)
- Counterargument: Be Careful With Return Types In TypeScript