[英]Typescript pattern matching with subtype of string literal type
export interface Action{
type: string;
}
export interface LoadTodos {
type: "LOAD_TODOS_ACTION"
}
export interface AddTodo {
type: "ADD_TODO_ACTION",
todo: Todo
}
export type KnownAction = LoadTodos | LoadTodosSuccess | AddTodo;
function isSomeType<T extends KnownAction>(x: any): x is T {
return x && typeof (x.type) === "LOAD_TODOS_ACTION";
}
let knownAction: actions.KnownAction = { type: "LOAD_TODOS_ACTION" };
if (isSomeType(knownAction)) {
let loadTodosAction = knownAction; // load Todos type
}
我期望上面的行為。 我想以一種通用的方式做到這一點,所以我不想重復isSomeType函數中的else語句。基本上我想基於'type'屬性將字符串文字類型轉換為適當的類型。 我的嘗試是這樣做:
function isSomeType<T extends Action>(x: any): x is T {
type p1 = T['type'];
return x && typeof (x.type) === p1;
}
但是消息顯示:“ p1”僅引用類型,但在此處用作變量。
有沒有辦法做到這一點?
令人驚訝的答案是:什么也不做。
function isSomeType<T extends KnownAction>(x: T):T {
return x;
}
基本上,只要調用具有上述簽名的函數,打字稿就會自動干擾打字。
編輯:
let knownAction: actions.KnownAction = { type: "LOAD_TODOS_ACTION" }; // KnownAction type
let knownAction2 = isSomeType(knownAction) // LoadTodosAction type
這不是一個明確的答案,但我不相信您可以。
FWIW推薦的方法可能是更改區分成員 。
至於您的代碼,您可能會丟失類型信息丟失的位置。 typeof
運算符在這里沒有意義。 typeof
是一個運行時操作,即使您在運行時在代碼中type: "LOAD_TODOS_ACTION"
, typeof x.type
也將返回string
,我希望這對您沒有幫助。 字符串文字類型意味着唯一可接受的可分配值是該字符串,而不是引入了新類型。
因此,為了實現您的期望,我們需要能夠獲取接口成員的編譯時類型信息。 據我所知,沒有辦法做到這一點。 如果有一個,這是可能的,但是直到那時我都不相信。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.