MageCoders
MageCoders

Reputation: 3

TypeScript ignoring internal function logic when infering return type?

Given the following type definition and function:

type SetResponseType = 'returnNumber' | 'returnString';

const argumentTypedFunction = (arg: SetResponseType) => {
    if (arg === 'returnNumber') {
        return 123;
    }

    return 'abc';
}


argumentTypedFunction('returnNumber'); // 123 | 'abc'

Why doesn't typescript knows that the return type could only be of type number when 'returnNumber' is used as argument? What do I have to do to make typescript infer the correct type depending on the parameter value?

Upvotes: 0

Views: 41

Answers (1)

jsejcksn
jsejcksn

Reputation: 33691

You can define your function using a function overload signature and get the inferred return type that you expect. Here's a code sample using the example data you showed in the question:

TS Playground

/** This signature returns a number when the parameter is "returnNumber" */
function argumentTypedFunction (param: 'returnNumber'): number;
/** This signature returns a string when the parameter is "returnString" */
function argumentTypedFunction (param: 'returnString'): string;
/** This is the implementation signature. It describes a combination of all possibilities */
function argumentTypedFunction (param: 'returnNumber' | 'returnString'): number | string {
  return param === 'returnNumber' ? 123 : 'abc';
}

const num = argumentTypedFunction('returnNumber');
    //^? const num: number

const str = argumentTypedFunction('returnString');
    //^? const str: string

argumentTypedFunction('somethingElse'); /* Expected error 👍
                      ~~~~~~~~~~~~~~~
No overload matches this call...(2769) */


Inference is ok, but being explicit is much better: it defines expectations of the types related to your code very clearly — both for you and consumers of your code — and can help the compiler to better help you in some cases if you accidentally make mistakes in your function implementation.

Upvotes: 1

Related Questions