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

时间:2021-01-17 19:50:01

标签: typescript function parameters string-literals inference

这是一个解释我要问什么的例子!

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

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

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

Playground Link