![](/img/trans.png)
[英]Check types in argument of generic function and return object literal type of this argument
[英]Variable return types based on string literal type argument
我可以根据 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 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 orange: string[] = doSomething("orange");
let apple: string = doSomething("apple");
尝试将doSomething("apple")
分配给orange
会产生编译时类型错误:
let orange: string[] = doSomething("apple");
// ^^^^^^
// type 'string' is not assignable to type 'string[]'
需要注意的是,确定使用哪个重载签名必须始终在函数实现中手动完成,并且函数实现必须支持所有重载签名。
TypeScript 中的每个重载没有单独的实现,例如在 C# 中。 因此,我发现在运行时加强 TypeScript 类型检查是一个很好的做法,例如:
switch (foo) {
case "apple":
return "hello";
case "orange":
return ["hello", "world"];
default:
throw new TypeError("Invalid string value.");
}
我有一个更好的方法。 使用泛型然后用作参数的类型(这样你就不需要手动传递泛型,typescript 会自动推断它)。 然后您可以使用该类型并选择正确的返回类型。
type Fruit = 'apple' | 'orange';
function doSomething<P extends Fruit>(foo: P): ({ apple: string; orange: string[] })[P] {
if (foo === 'apple') return 'hello';
return ['hello','world];
}
const x: string = doSomething('apple');
const y: string[] = doSomething('orange');
通过这种方式,您可以根据自动传递的参数更改函数的返回类型。
是的,你可以。 您只需要使用instanceof
测试您的test
变量。 然后打字稿将限制类型。
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的答案要好得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.