ts 泛型引用问题?

今天面试遇到一道题,想了很久也没有想出来

type Events = {
  ready: void
  error: Error
  reconnecting: { attempt: number; delay: number }
}

type RedisClient = {
  on<T extends keyof Events>(event: T, f: (arg: Events[T]) => void): void
}

let aa: RedisClient = 
这里要怎么写

aa.on('ready', () => {
  console.log(12312)
})

我是这样写的,但是报错了

let aa: RedisClient = {
  on: function (event, f): void {
    switch (event) {
      case 'ready':
        f()
        break
      case 'error':
        f(new Error())
        break
      case 'reconnecting':
        f({ attemp: 1, delay: 1 })
        break
      default:
        break
    }
  }
}

f()的参数有问题,想请教一下大家应该如何写?

阅读 2.2k
4 个回答
type Events = {
  ready: void
  error: Error
  reconnecting: { attempt: number; delay: number }
}

type RedisClient = {
  on<T extends keyof Events>(event: T, f: (arg: Events[T]) => void): void
}

let aa: RedisClient = {
  on: function<T extends keyof Events> (event: T, f: (arg: Events[T]) => void): void {
    switch (event) {
      case 'ready':
        f(undefined as Events[T]); // 无参数
        break;
      case 'error':
        f(new Error() as Events[T]); // Error参数
        break;
      case 'reconnecting':
        f({ attempt: 1, delay: 1 } as Events[T]); // 对象参数
        break;
      default:
        break;
    }
  }
}

aa.on('ready', () => {
  console.log('Ready event')
})

aa.on('error', (e: Error) => {
  console.log('Error event', e)
})

aa.on('reconnecting', (arg: { attempt: number; delay: number }) => {
  console.log('Reconnecting event', arg.attempt, arg.delay)
})
type RedisClient<T extends keyof Events> = {
  on(event: T, f: (arg: Events[T]) => void): void
}

只能这样改了,不然就只能强行as

新手上路,请多包涵
type Events = {
    ready: void
    error: Error
    reconnecting: { attempt: number; delay: number }
}

type RedisClient = {
    on<T extends keyof Events>(event: T, f: (arg: Events[T]) => void): void
}

let aa: RedisClient = {
    on(event, f): void {
        switch (event) {
            case 'ready':
                (f as ((arg: Events["ready"]) => void))();
                break
            case 'error':
                (f as ((arg: Events["error"]) => void))(new Error())
                break
            case 'reconnecting':
                (f as ((arg: Events["reconnecting"]) => void))({ attempt: 1, delay: 1 })
                break
            default:
                break
        }
    }
}

aa.on('ready', () => {
    console.log(12312)
})

只能这么写了

let aa: RedisClient = {
    on(event, fn) {
        const redis: Events = {
            ready: undefined,
            error: new Error('error massage'),
            reconnecting: {
                attempt: 3,
                delay: 300
            }
        }
        fn(redis[event])
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Microsoft
子站问答
访问
宣传栏