Setting
class X {
constructor(first: string, ...rest: string[]) { }
}
new X(...["foo", "bar"])
yields the error
A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556)
This is working:
new X("foo", ...["bar"])
but that's not very handy.
If I use
class X {
constructor(...all: string[]) { }
}
instead it's working fine, so it must have something to do with me splitting into first
and rest
. But is there a way to make this work with split arguments?
CodePudding user response:
The type of ["foo", "bar"]
is string[]
. If you can't control the type of this with as const
, because you got it elsewhere, you can validate and narrow the type, for example:
const input:string[] = ["foo", "bar"];
if (!input.length<1) {
throw new Error('Input must at least have 1 element');
}
const tuple: [string, ...string[]] = [input[0], ...input.slice(1)];
}
If the assignment feels silly, I feel this is way more elegant:
const input:string[] = ["foo", "bar"];
function assertAtLeast1Element(input: string[]): asserts input is [string, ...string[]] {
if (input.length < 1) throw new Error('Input must at least have 1 element');
}
assertAtLeast1Element(input);
class X {
constructor(first: string, ...rest: string[]) { }
}
new X(...input);