Reputation: 23543
I have a function where the first argument must be a string. There can be an unlimited number of arguments after that or none at all:
const myFunction = (arg1: string, ...rest: any) {
// do stuff
}
Can I make a type or interface that specifies both arg1
and ...rest
? I'm asking as other functions have the same arguments and I'd like to reuse the typings.
Upvotes: 0
Views: 4165
Reputation: 121964
You can do this by taking an answer from TypeScript array with minimum length, and using it as the type for a rest argument, for example:
type OneOrMore<T> = { 0: T } & Array<T>;
// or allow the rest to be a wider type, like any:
// type OneOrMore<T, S extends T = T> = { 0: T } & Array<S>;
You can either define a function type using this:
type MyFunction = (...args: OneOrMore<string>) => void;
const myFunction: MyFunction = (...args) => { /* use args */ };
or use it directly:
function anotherFunction(...args: OneOrMore<string>) { /* use args */ }
Now calling with one or more arguments is permitted, but calling with no arguments gives e.g.
Argument of type '[]' is not assignable to parameter of type 'OneOrMore<string>'.
Property '0' is missing in type '[]' but required in type '{ 0: string; }'.
However, note that your implementation can't name that first parameter independently; the following:
const myFunction: MyFunction = (arg, ...args) => { /* use arg and args */ };
results in:
Type '(arg: string, ...args: string[]) => void' is not assignable to type 'MyFunction'.
Types of parameters 'arg' and 'args' are incompatible.
Type 'OneOrMore<string>' is not assignable to type '[arg: string, ...args: string[]]'.
Upvotes: 1