簡體   English   中英

依賴泛型參數作為 function 的值參數的類型

[英]Type that depends on generic argument as value argument to function

我有一個看起來像這樣的通用類型Group

// K -> Key
// I -> Input
type Group<K, I> = {
    key: K;
    func: (i: I) => void;
};

我在 object 中聲明了固定數量的Group值,如下所示:

const GROUPS = {
    "a": {
        func: (i: {x: number}) => { console.log(i); },
        key: "a",
    },
    "b": {
        func: (i: { y: number }) => { console.log(i) },
        key: "b"
    }
} as const;

然后,我有 2 種實用程序類型來引用所有可能的組鍵和所有可能的組輸入:

type GroupKey = keyof typeof GROUPS;
type GroupInput<K extends GroupKey> = Parameters<typeof GROUPS[K]["func"]>[0];

// GroupValue test:
type TestType = GroupInput<"b">; // { y: number}, this works

最后,我有一個 function 接收組鍵和組輸入:

function test<K extends GroupKey>(key: K, input: GroupInput<K>) {
    if (key === "b") {
        (input.y); // Why doesn't TypeScript understand that `input.y` must be `number` here?
    }
}

這個 function 對於傳入的鍵的類型是通用的,不幸的是,TypeScript 無法“理解”如果key"b" ,那么input的類型是{ y: number } 為什么會出現這種情況,TypeScript 缺少什么才能做到這一點? 我特別想在這個問題上找到一個 GitHub 問題(以便我可以訂閱它),但我無法找到一個,因為這種類型的東西特別難以搜索。

全游樂場 URL

請考慮這個片段:

const key = 'a' as GroupKey
const input = { y: 1 } // optionally cast as GroupInput<'b'> or as GroupInput<GroupKey>

test(key, input) // compiles, but not intended

input可能獨立於key 不能保證input.y必須是一個數字,當test被調用時,值'b'作為第一個參數。 type TestType = GroupInput<"b">使用文字類型( 'b' ),它允許 Typescript 限制'a' | 'b' 'a' | 'b''b' 這同樣適用於test('b', ...) ,但傳遞類型為'a' | 'b' 'a' | 'b'允許傳遞GroupInput<'a' | 'b'>類型的輸入 GroupInput<'a' | 'b'>

一種選擇是檢查'y' in input ,但這仍然不能解決不允許錯誤的 arguments 進行test的主要問題。 通常情況下input as GroupInput<'b'>是不安全的,應不惜一切代價避免。

一個可能的修復:

type Params = { [K in GroupKey]: [key: K, input: GroupInput<K>] } // key: and input: are used for auto-completion instead of generic arg_0, arg_1

function test2(...args: Params[GroupKey]) {
    // const [key, input] = args // will not work
    if (args[0] === "b") {
        const input = args[1];
        input.y; // number
    }
}

test2('b', { y: 1 }) // ok
test2('b', { x: 1 }) // error
test2(key, input) // error

操場

因為input參數獨立於您的key參數。 盡管您的鍵可能等於'b' ,但input不需要將y作為屬性。 您必須對您的input進行類型轉換:

 function test<K extends GroupKey>(key: K, input: GroupInput<K>) {
    if (key === "b") {
        const typedInput = input as GroupInput<'b'>;
        (typedInput.y)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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