我有一個簡單的聯合類型的字符串文字,需要檢查它的有效性,因爲FFI調用「正常」的Javascript。有沒有一種方法可以確保某個變量是運行時處的任何字符串的實例?沿着使用type
在運行時檢查字符串文字聯合類型的有效性?
type MyStrings = "A" | "B" | "C";
MyStrings.isAssignable("A"); // true
MyStrings.isAssignable("D"); // false
我有一個簡單的聯合類型的字符串文字,需要檢查它的有效性,因爲FFI調用「正常」的Javascript。有沒有一種方法可以確保某個變量是運行時處的任何字符串的實例?沿着使用type
在運行時檢查字符串文字聯合類型的有效性?
type MyStrings = "A" | "B" | "C";
MyStrings.isAssignable("A"); // true
MyStrings.isAssignable("D"); // false
既然Typescript 2.1,你可以通過with the keyof
operator。
這個想法如下。由於字符串文字類型信息在運行時不可用,因此您將定義一個帶鍵的普通對象作爲字符串文字,然後創建該對象的鍵類型。
如下:
// Values of this dictionary are irrelevant
const myStrings = {
A: "",
B: ""
}
type MyStrings = keyof typeof myStrings;
isMyStrings(x: string): x is MyStrings {
myStrings.hasOwnProperty(x);
}
const a: string = "A";
if(isMyStrings(a)){
// ... Use a as if it were typed MyString from assignment within this block: the TypeScript compiler trusts our duck typing!
}
東西線只是Type Aliasing和編譯,因爲那javascript代碼,它不會出現你不能真正做到:
MyStrings.isAssignable("A");
,你能做些什麼它:
type MyStrings = "A" | "B" | "C";
let myString: MyStrings = getString();
switch (myString) {
case "A":
...
break;
case "B":
...
break;
case "C":
...
break;
default:
throw new Error("can only receive A, B or C")
}
至於你問有關isAssignable
,您可以:
function isAssignable(str: MyStrings): boolean {
return str === "A" || str === "B" || str === "C";
}
這個工作,但休息一旦'MyStrings'而不更新對應的'isAssignable'功能擴展。我希望減輕體力負擔。 –
你可以做的事情不多。正如我寫的,'type'部分是嚴格的打字稿,並且這些信息在生成的js文件中丟失。你可以使用'enum'而不是''''。 –
如果您願意付出努力,您可以編寫一個工具來生成定義類型的TS代碼,以及運行時類型從其他數據源執行檢查的TS代碼。我已經研究過使用C#編寫REST API的代碼,並且我們將C#數據合約編譯成TS,既包括類型定義,也包括描述類型的運行時反觀對象字面值。可以理解的是,所有這些都超出了TS的範圍。 – Alan