问题描述
这是一个解释我要问什么的例子!
// Given an events deFinition
interface IEventDef {
event1: () => void,event2: (data: T) => void
// ...
}
它如何声明如下内容:
public on(
eventName: keyof IEventsDeFinitions,// get the literal string here (when it's used)
callback: IEventsDeFinitions[EventName] // and use it on the next param type ???
) {
}
关键是如何做出这样的定义,以便我们在编写时:
obj.on('event1',(data) => {
// need data to be correctly infered and that using the string literal 'event1'! Technically that is possible to be done
// as it is,it doesn't inference
})
// 需要正确推断数据并使用字符串文字“event1”!技术上可以做到
实际上,它不会进行推理!
也知道这样的解决方法有效:
public on<EventName extends keyof IEventsDeFinitions>(
eventName: keyof IEventsDeFinitions,callback: IEventsDeFinitions[EventName]
) {
并像这样使用它:
on<"event1">('event1',(data) => {})
数据将被正确推断!但是很丑! (技术上可以从字面推断)!
所以我在问我们怎么能以任何方式做到这一点!?提前谢谢你!
解决方法
您的解决方法版本大部分是正确的,您缺少的部分是 eventName
和 callback
参数需要引用 相同 键。
您需要 eventName: keyof IEventsDefinitions
而不是 eventName: EventName
,其中 eventName
参数的值与函数的通用变量匹配。
function on<EventName extends keyof IEventsDefinitions>(
eventName: EventName,callback: IEventsDefinitions[EventName]
) {
您不再需要在调用函数时指定泛型,因为现在 typescript 能够从第一个参数推断泛型。
on('event1',() => {})
on('event2',(data) => {})