簡體   English   中英

打字稿模式與字符串文字類型的子類型匹配

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM