我想要的是
我有一个对象和一个“消费者”函数,它接受一个键和处理程序函数,然后将该键的值传递给处理程序。
我希望 Typescript 在运行时给定任意键来推断处理函数的正确类型。
我希望它使用密钥作为正确处理程序的“选择器”,并在使用该处理程序时具有类型安全性。我知道我可以在给定密钥的处理程序中手动键入参数,但我希望自动推断它以具有适当的类型安全性。例如,如果我更改键而不是处理程序的实现,则中断。
我试过的
type Things<T> = {
[K in keyof T]: T[K]
}
type ThingConsumer<T, K extends keyof T> = (
forThingOfType: K,
handler: (value: T[K]) => void,
) => void
function createThings<T>(things: Things<T>): Things<T> {
return things
}
function createThingConsumer<T, K extends keyof T>(
things: Things<T>,
): ThingConsumer<T, K> {
return (forThingOfType, handler) => handler(things[forThingOfType])
}
const things = createThings({
a: { foo: 1, bar: 2 },
b: { baz: 3 },
})
const thingConsumer= createThingConsumer(things)
thingConsumer('a', (value) => {
console.log(value.foo + 1) // <-- error: Object may be 'undefined'
})
什么不起作用
看来 Typescript 无法从传递的密钥中value正确推断出具体类型, .{ foo: number, bar: number }'a'
相反,它推断value为 的所有可能值的联合类型things,即
{ foo: number, bar: number } | { baz: number }
然后尝试使用时的错误信息value.foo是非常意外的。它说“对象”可能是未定义的。如果有的话,我会期望它抱怨foo可能是未定义的,考虑到联合类型推断,但不是它value本身可能是未定义的。
我正在尝试做的事情可能吗?
感觉应该是这样 - 特别是我真的认为T[K]语法说“对于一个给定K的对象的具体键,解析相应值的类型”。但也许它没有那么强大,而是说'对于任何键,解决任何值'?