Specify rest arguments first in Typescript

129 views Asked by At

I have a function which receives a variable number of arguments (each of type string), and a final argument (of a complex type, called Expression).

In JavaScript, this looks like:

function layerProp(...args) {
  const fields = args.slice(0, -1)
  const fallbackExpression = args.slice(-1)[0]

How can I write a type definition for this function?

4

There are 4 answers

1
brk On

For the function argument you can write as ...args: string[], From the function implementation fallbackExpression is a simple string. So it would be better to use a interface instead of a type

function layerProp(...args: string[]) {
  const fields = args.slice(0, -1)
  const fallbackExpression = args.slice(-1)[0]
  // rest of the code
}
0
MysticCode On

You can declare a union type like:

(string | Expression)[]

Then your code becomes:

function layerProp(...args: (string | Expression)[]) {
  const fields = args.slice(0, -1)
  const fallbackExpression = args.slice(-1)[0]
  // rest of the code
}
4
Samer Murad On

If your method gets one complex Expression object, and a bunch of strings, you might want to consider flipping the positions of the arguments, and then you can do this:

function layerProp(expression: Expression, ...fields: strings[]) {
  // ... your code
} 
0
wonderflame On

You can use the following type:

function layerProp(...args: [...string[], Expression]) {}

However, it won't type the slice and the easiest solution would be just to assert the last element to Expression as follows:

function layerProp(...args: [...string[], Expression]) {
  const fields = args.slice(0, -1);
  const fallbackExpression = args.slice(-1)[0] as Expression;
}

Usage:

type Expression = {
  a: string;
}

layerProp('a', 'b', 'c', { a: 'sd' });
layerProp('a', 'b', 'c', { a: 'sd' }, 'a'); // expected error
layerProp('a', 'b', 'c', 'a'); // expected error

playground