Typescript类型参数

在学习ts,仿写emitter时,发现参数类型不兼容的问题

type EventType = string | symbol;

type Handler<T = unknown> = (event: T) => void;

interface IEmitter<Events extends Record<EventType, unknown>> {
    on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void
}

function emitter<Events extends Record<EventType, unknown>>():IEmitter<Events> {
    type EventHandler = Handler<Events[keyof Events]>
    return {
        // 这块报错
        on<Key extends keyof Events>(type: Key, handler: EventHandler) {}
    }
}

一下为报错信息:

不能将类型“<Key extends keyof Events>(type: Key, handler: Handler<Events[keyof Events]>) => void”分配给类型“<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>) => void”。
  参数“handler”和“handler” 的类型不兼容。
    参数“event”和“event” 的类型不兼容。
      不能将类型“Events[keyof Events]”分配给类型“Events[Key]”。
        不能将类型“keyof Events”分配给类型“Key”。
          "keyof Events" 可赋给 "Key" 类型的约束,但可以使用约束 "string | number | symbol" 的其他子类型实例化 "Key"。
            不能将类型“string | number | symbol”分配给类型“Key”。
              "string | number | symbol" 可赋给 "Key" 类型的约束,但可以使用约束 "string | number | symbol" 的其他子类型实例化 "Key"。
                不能将类型“string”分配给类型“Key”。
                  "string" 可赋给 "Key" 类型的约束,但可以使用约束 "string | number | symbol" 的其他子类型实例化 "Key"。ts(2322)

求大佬指教一下ts报错原因

阅读 3k
1 个回答

这样写

function emitter<Events extends Record<EventType, unknown>>(): IEmitter<Events> {
  return {
    on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>) {},
  }
}

emitter<{
  'name': string
  'age': number
}>().on('age', (value) => {
// number
  console.log(value)
})

emitter<{
  'name': string
  'age': number
}>().on('name', (value) => {
//    string
  console.log(value)
})

你单独写了type EventHandler = Handler<Events[keyof Events]>这个类型, 结果是一个参数为所有key的联合类型的函数, 当然就不匹配了

例:

interface Events {
  'name': string
  'age': number
}
// 结果 (event: string | number) => void
type EventHandler = Handler<Events[keyof Events]>

此时如果传入name, 对应的前面应该是(event: string) => void, 当然就和(event: string | number) => void不兼容了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题