![](/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.