Reputation: 863
I know that Typescript will automatically infer if the output is an array or not, but I'm trying to figure out how to set it explicitly using conditional type.
I've tried something like the below, but it doesn't seem to work.
function test<T>(...args:any[]): T extends any[] ? any[] : any {
// If there is only 1 arg, return a string
if(args.length === 1)
return 1;
// If there is more than 1 args, return an array
else
return [1,2,3]
}
Does anybody know what I'm doing wrong?
Upvotes: 1
Views: 48
Reputation: 1074038
The error it gives (2322) is the same as the error you get with code like this:
function example<T>(x: number | string): T {
if (typeof x === "number") {
return x * 2;
}
return x + x;
}
Type 'number' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'number'. (2322)
What that's saying is that I can write code like this:
example<object>(42);
...and then T
is object
, but neither number
nor string
is assignable to object
.
The same applies to your test
function.
I think you were just experimenting with conditional types, but just for completeness, as you say the TypeScript compiler could infer those return values, but it would infer a union type, in that specific case 1 | number[]
. If you wanted to tell TypeScript that test
with one argument returns number
and test
with more than one argument returns number[]
, you can do that with a function overload:
function test(x: any): number;
function test(x: any, y: any, ...more: any[]): number[];
function test(...args:any[]): number | number[] {
// If there is only 1 arg, return a string
if(args.length === 1)
return 1;
// If there is more than 1 args, return an array
else
return [1,2,3]
}
const x = test(1); // type of `x` is `number`
const y = test(1, 2, 3); // type of `y` is `number[]`
Upvotes: 1