Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to infer return type from parameter type in a generic function?

Here is some code with conditional type

class A {
    public a: number;
}

class B {
    public b: number;
}

type DataType = "a" | "b";

type TData<T extends DataType> =
    T extends "a" ? A :
    T extends "b" ? B :
    never;

Now I want to use conditional type as a link from function parameter to its return type. I tried to achieve this in different ways with no result:

function GetData<T extends DataType>(dataType: T): TData<T> {
    if (dataType == "a")
        return new A();
    else if (dataType == "b")
        return new B();
}

What is the proper syntax? Is it possible with TypeScript 2.8?

Update

There is already an opened issue on github that covers my example. So current answer is "No, but may be possible in future".

like image 330
Andrey Godyaev Avatar asked Sep 12 '18 20:09

Andrey Godyaev


People also ask

What is inferred return type?

The return type is inferred by the return statements e.g. the following function is inferred to return a number . function add(a: number, b: number) { return a + b; } This is an example of types flowing bottom out.

What is infer in TypeScript?

TypeScript infers types of variables when there is no explicit information available in the form of type annotations. Types are inferred by TypeScript compiler when: Variables are initialized. Default values are set for parameters. Function return types are determined.

What is generic type in Javascript?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.


1 Answers

You can use function overloads here:

function GetData(dataType: "a"): A;
function GetData(dataType: "b"): B;
function GetData(dataType: DataType): A | B {
    if (dataType === "a")
        return new A();
    else if (dataType === "b")
        return new B();
}

const f = GetData('a');  // Inferred A
const g = GetData('b');  // Inferred B
like image 74
EyasSH Avatar answered Sep 22 '22 23:09

EyasSH