打字稿:如何推断字符串文字参数类型并将其用于另一个参数类型

Typescript: how to inference a string literal param type and use it on another param type

这里有一个例子可以解释我的问题!

// 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) => {})

数据将被正确推断!但是很丑! (并且从字面技术上推断是可能的)!

所以我想问我们怎么能以任何方式做到这一点!?提前致谢!

您的解决方法版本大部分是正确的,您缺少的部分是 eventNamecallback 参数需要引用 same 键。

而不是 eventName: keyof IEventsDefinitions,您需要 eventName: EventName,其中 eventName 参数的值与函数的通用变量相匹配。

function on<EventName extends keyof IEventsDefinitions>(
    eventName: EventName,
    callback: IEventsDefinitions[EventName]
) {

您不再需要在调用函数时指定泛型,因为现在打字稿能够从第一个参数推断出泛型。

on('event1', () => {})

on('event2', (data) => {})

Playground Link