sydd
sydd

Reputation: 1946

TypeScript: How to make a conditional type that returns an array based on the condition?

I am trying to type a function that should return an array type, if the input parameter is array type, and a normal parameter otherwise. Here's my attempt:

function test<T extends number|number[]>(a: T):T extends number[] ? string[] : string {
  if (Array.isArray(a)) {
    return ['123', '45']
  }
  return '123'
}

I get an error at the return statements: Type 'string' is not assignable to type 'T extends number[] ? string[] : string'.

What I'm looking for is the following:

const a = test(3) // "a" is string type
const b = test([1,2,3]) // "b" is string[] type

Upvotes: 5

Views: 1649

Answers (3)

Alireza Ahmadi
Alireza Ahmadi

Reputation: 9893

Based on this Typescript will not infer different return types based on type guards in the function. But you can define multiple function signatures like this:

function test(a: number): string;
function test(a: number[]): string[];

function test<T extends number|number[]>(a: T): string | string[]{ 
  if (Array.isArray(a)) {
    return ['123', '45'] 
  }
  let str = '123'
  return str;
}

const a = test(3) //string
const b = test([1,2,3]) //string[]

PlaygroundLink

Also see this issue: https://github.com/microsoft/TypeScript/issues/24929

Upvotes: 2

Markus
Markus

Reputation: 2062

Union based return types are currently not supported by typescript but there is a workaround for this kind of problem.

function test<T extends number|number[]>(a: T):T extends number[] ? string[] : string {
  if (Array.isArray(a)) {
    return ['123', '45'] as any
  }
  return '123' as any
}

See a working example here.

For more details read this issue on github

Upvotes: 0

Just use overload your function:

function test(a: number): '123'
function test(a: number[]): string[]
function test<T extends number | number[]>(a: T) {
    if (Array.isArray(a)) {
        return ['123', '45']
    }
    return '123'
}
test(2) // '123'
test([23]) // string[]

No need in conditional types.

Playground

Upvotes: 3

Related Questions