Peter Lehnhardt
Peter Lehnhardt

Reputation: 4995

Union type function "overloading" not working

I tried to "overload" a function by setting it to a union function type so that the type of the given parameter sets the type of the member data in the returned object. But it throws an error:

type FN1 = (a: string) => {data: string};
type FN2 = (b: number) => {data: number};
    
const fn: FN1 | FN2 = c => ({data: c});
    
fn('some string');
   ^^^^^^^^^^^^^  <= Argument of type 'string' is not assignable to parameter of type 'never'.

The type of fn is displayed as

const fn: (arg0: never) => {data: string} | {data: number}

Why is the parameter of type never? Is there some other way to make it possible?

SandBox Link

Upvotes: 0

Views: 281

Answers (2)

Linda Paiste
Linda Paiste

Reputation: 42258

This is a good case for generics since your return type can be easily typed from your input type.

For any value:

const fn = <T>(c: T): {data: T} => ({data: c});

For string and number only:

const fn = <T extends string | number>(c: T): {data: T} => ({data: c});

Upvotes: 1

Martin
Martin

Reputation: 2283

For your need, I would simply use a generic function:

function fn1<T>(data: T) {
  return { data };
}

Of course it can be solved with function overloading as well (note: this would not work in your codesanbox becaues eslint has an error with redeclaring the function, but it is valid in typescript and it is an error in eslint):

function fn1(data:string): {data: string};
function fn1(data:number): {data: number};
function fn1(data: any): any {
    return {data};
}

fn1("some string");
fn1(1);

Upvotes: 0

Related Questions