Typescript 依赖于泛型参数作为函数值参数的类型

Typescript 依赖于泛型参数作为函数值参数的类型,typescript,Typescript,我有一个通用类型组,如下所示: // K -> Key // I -> Input type Group<K, I> = { key: K; func: (i: I) => void; }; const GROUPS = { "a": { func: (i: {x: number}) => { console.log(i); }, key: "a", },

我有一个通用类型
,如下所示:

// K -> Key
// I -> Input
type Group<K, I> = {
    key: K;
    func: (i: I) => void;
};
const GROUPS = {
    "a": {
        func: (i: {x: number}) => { console.log(i); },
        key: "a",
    },
    "b": {
        func: (i: { y: number }) => { console.log(i) },
        key: "b"
    }
} as const;
然后,我有两种实用程序类型来引用所有可能的组键和所有可能的组输入:

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
type GroupKey=typeof组的键;
类型GroupInput=参数[0];
//组值测试:
类型TestType=GroupInput;//{y:number},这是有效的
最后,我有一个函数,它接收组键和组输入:

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?
    }
}
功能测试(键:K,输入:GroupInput){
如果(键==“b”){
(input.y);//为什么TypeScript不明白这里的'input.y'必须是'number'?
}
}
此函数在传入的键的类型上是通用的,不幸的是,TypeScript无法“理解”如果
key
“b”
,则
输入的
类型为
{y:number}
。为什么会出现这种情况,TypeScript缺少什么才能做到这一点?我特别想在这方面找到一个GitHub问题(这样我就可以订阅),但我没能找到,因为这类东西特别难搜索


因为
输入
参数独立于
参数<代码>输入
不需要将
y
作为属性,尽管您的键可能等于
'b'
。您必须键入您的
输入

 function test<K extends GroupKey>(key: K, input: GroupInput<K>) {
    if (key === "b") {
        const typedInput = input as GroupInput<'b'>;
        (typedInput.y)
    }
}
功能测试(键:K,输入:GroupInput){
如果(键==“b”){
const typedInput=作为组输入的输入;
(typedInput.y)
}
}

<代码> < p>请考虑此片段:

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

我还没有看到你的答案。我已经删除了我的答案。类型转换不是一个很好的解决方案,它很危险,所以我想避免它。不幸的是,没有办法解决这个问题,因为您无法确保您的GroupInput属于同一个密钥。
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