Evanss
Evanss

Reputation: 23543

Interface for function with multiple arguments?

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

Answers (1)

jonrsharpe
jonrsharpe

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; }'.

Playground


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

Related Questions