我有一个通用类型Group
看起来像这样:
// K -> Key
// I -> Input
type Group<K, I> = {
key: K;
func: (i: I) => void;
};
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 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?
}
}
遗憾的是,此函数在传入的密钥类型上是通用的,不幸的是,TypeScript无法“理解”如果key
is "b"
,input
则为type { y: number }
。为什么会这样,TypeScript缺少什么才能做到这一点?我特别想在此找到一个GitHub问题(以便我可以订阅它),但是我找不到一个,因为这种类型的东西特别难找。
请考虑以下代码段:
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
以value'b'
作为第一个参数调用时必须有一个数字。type TestType = GroupInput<"b">
使用文字类型('b'
)允许Typescript限制'a' | 'b'
为just 'b'
。相同test('b', ...)
,但类型的传递键'a' | 'b'
允许传递类型的输入GroupInput<'a' | 'b'>
。
一种选择是检查是否'y' in input
,但是仍然不能解决不允许错误参数传递的主要问题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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句