我可以根据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 '字符串[]'。
答案 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
这样,您可以根据自动传递的参数更改函数的返回类型。