基于字符串文字类型参数的变量返回类型

时间:2016-09-26 10:12:24

标签: typescript

我可以根据TypeScript 1.8或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");
  

错误:TS2322:输入'string | string []'不能赋值给type   '字符串[]'。

3 个答案:

答案 0 :(得分:29)

是的,您可以使用过载签名来实现您想要的目标:

type Fruit = "apple" | "orange"

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

let test1: string[] = doSomething("orange");
let test2: string = doSomething("apple");

Live demo on TypeScript Playground

尝试将doSomething("apple")分配给test1会产生编译时类型错误:

let test1: string[] = doSomething("apple");
 // ^^^^^
 // type string is not assignable to type string[]

重要的是要注意,确定使用哪个重载签名必须始终在函数实现中手动完成,并且函数实现必须support all overload signatures

TypeScript中的每次重载没有单独的实现,例如C#。因此,我发现在运行时强化TypeScript类型检查是一种很好的做法,例如:

switch (foo) {
    case "apple":
        return "hello";
    case "orange":
        return ["hello", "world"];
    default:
        throw new TypeError("Invalid string value.");
}

答案 1 :(得分:1)

是的,你可以。您只需要使用test测试instanceof变量。然后,Typescript将限制类型。

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[]) {}

<强>更新

你可能只想让方法变得通用。

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");

或者另一种选择是将流程反转为:

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

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

<强>更新

实际上我相信 John White 是一个更好的答案。

答案 2 :(得分:1)

我有一个更好的方法。使用一个泛型,然后将该泛型用作参数的类型(因此,您无需手动传递该泛型,而Typescript会自动推断出它)。然后,您可以使用该类型并选择正确的返回类型。

botocore==1.12.133

这样,您可以根据自动传递的参数更改函数的返回类型。