user12499410
user12499410

Reputation: 402

return type of function based on argument value existence in TypeScript

I have the following function in index.js file:

function myFn(val) {
  if (val) {
    return val;
  }
  return console.log(val);
}

I have the following type declaration in index.d.ts file:

declare function myFn<T>(val?: T): (T | void);

But the problem is that if i pass no arguemnt then there is no case where the function can return any value other than void type.

I would like to do something like this:

declare function myFn<T>: (val?: T) => (val ? T : void);

How can i implement this best? any ideas?

Upvotes: 1

Views: 47

Answers (3)

Jerome
Jerome

Reputation: 2761

@Alex 's answer is correct, I was just writting these examples that shows the way to use generics in different ways to avoid messing up the return type:

declare function myFn<T=void>(val?:T ):T  ;
const tvoid = myFn() // <-- type is void 
const tsds = myFn("sds") // <-- type is "sds" and not string
const tstring:string = myFn("sds") // <-- type is string  
const tstring2 = myFn<string>("sds") // <-- type is string  
const tnumber = myFn<number>(3) // <-- type is number
const t3 = myFn(3) // <-- type is 3

AFAIC, I prefer const tstring2 = myFn<string>("sds") that I find more "elegant"

Upvotes: 1

Alex Wayne
Alex Wayne

Reputation: 187004

That's not valid syntax, but I am going to assume you meant this:

declare function myFn<T>(val?: T): (T | void);

The problem here is that val is absent, the type T is not knowable, so typescript infers it as unknown.

To fix it, you need to give your generic parameter a default value for the case when there is no argument. Now typescript knows exactly what to use when val is omitted and doesn't have to guess.

declare function myFn<T = void>(val?: T): T;

const iAmVoid: void = myFn()
const iAmString: string = myFn('a string')

Playground

Upvotes: 1

Brooke Hart
Brooke Hart

Reputation: 4049

You can use function overloads to determine the return type of a function based on the arguments passed to it. For example:

function myFn<T>(): void
function myFn<T>(val: T): T
function myFn<T>(val?: T): T | void {
  if (val) {
    return val;
  }
  return console.log(val);
}

TypeScript Playground

Upvotes: 2

Related Questions