typescript - 打字稿泛型:将键作为函数 arg 传递,将另一个 arg 推断为值
问题描述
我想要的是
我有一个对象和一个“消费者”函数,它接受一个键和处理程序函数,然后将该键的值传递给处理程序。
我希望 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
的对象的具体键,解析相应值的类型”。但也许它没有那么强大,而是说'对于任何键,解决任何值'?
解决方案
<K extends keyof T>
应该作为返回函数的属性而不是高阶函数移动。
type ThingConsumer<T> = <K extends keyof T>(
forThingOfType: K,
handler: (value: T[K]) => void,
) => void
推荐阅读
- node.js - DiscordAPIError:未知消息(用于在消息上分配角色的机器人)
- macos - Qt 5.15 macOS:使用 QFontDatabase 加载字体的 QML 中的扭曲文本
- java - (尽管至少存在一个 Creator):没有 String-argument 构造函数/工厂方法可以从 String 值反序列化
- r - 使用 GMNL 包进行分析的离散选择实验数据准备
- rust - 如何使用 xpath 查询 xml
- python - 在非唯一但有条件选择非唯一值的列上合并 2 个 pandas 数据帧(技术上是唯一的)
- r - 我想合并两个 csv 文件,但是在为两个文件分配了一个识别变量之后≥
- selenium - 如何反转“action.KeyDown(Keys.Alt).SendKeys("N").Perform();” 在 C#、Seleium/Appium/Visual Studio 中
- python - Python 计划仅在代码执行后立即运行,而不是在请求的时间运行
- java - 使用条件获取连接路径中的字段