daniel.sedlacek daniel.sedlacek - 2 months ago 12
TypeScript Question

Variable return types based on string literal type argument

Can I have variable return type based on the value of a string literal type argument in TypeScript 1.8 or 2.0?

type Fruit = "apple" | "orange"
function doSomething(foo : Fruit) : string | string[] {
if (foo == "apple") return "hello";
else return ["hello","world"];
}

var test : string[] = doSomething("orange");



Error: TS2322: Type 'string | string[]' is not assignable to type
'string[]'.

Answer

Yes you can. You just need to test your test variable with instanceof. Typescript will then limit the type.

type Fruit = "apple" | "orange" 
function doSomething(foo: Fruit): string | string[] {
    if (foo == "apple") return "hello";
    else return ["hello","world"]
}

// here the type is still inferred as: string | string[]
var test = doSomething("orange");

if (test instanceof String) {
    // TypeScript knows test is type: string
    doSomethingWithString(test);
} else {
    // TypeScript knows test is type: string[]
    doSomethingWithStringArray(test);
}

function doSomethingWithString(input: string) {}
function doSomethingWithStringArray(input: string[]) {}

UPDATE

You may just want to make the method generic instead.

function doSomething<T>(foo: Fruit): T {
    if (foo == "apple") return "hello";
    else return ["hello","world"]
}

var test1 = doSomething<string>("apple");
var test2 = doSomething<string[]>("orange");

Or another option would be to invert the flow to something like this:

type Fruit = "apple" | "orange" 
function doSomething(foo: Fruit): string | string[] {
    if (foo == "apple") 
        doSomthingWithString("hello");
    else 
        doSomethingWithStringArray(["hello","world"]);
}

function doSomethingWithString(input: string) {}
function doSomethingWithStringArray(input: string[]) {}