TypeScript泛型监听回调未正确推导属性对应精准类型问题
TypeScript回调参数类型推导问题解答
推导为联合类型的原因
- 你定义的
on方法依赖泛型参数Key关联事件名和回调参数类型,但TypeScript目前不支持从模板字面量的入参反向推导泛型参数:传入的onBluetoothChanged是符合on${Capitalize<Key>}Changed规则的字面量,但TS没有能力自动拆解这个字符串得到对应的Key为bluetooth。 - 当泛型
Key无法被精准推断时,TS会自动把Key推导为符合约束的所有可能值的联合,也就是"paint" | "tires" | "brakes" | "bluetooth" | "mileage",对应的属性值类型T[Key]自然就是所有属性的类型联合string | number | boolean。
修复方案
你可以通过预生成事件名和回调类型的映射表规避反向推导的问题,修改后的PropChangeListener类型如下:
type PropChangeListener<T> = { // 遍历所有属性生成对应事件名和回调类型的映射 [K in string & keyof T as `on${Capitalize<K>}Changed`]: (val: T[K]) => T[K] } extends infer EventMap ? { // 直接从预生成的映射表匹配类型,无需反向推导 on<P extends keyof EventMap>(prop: P, callback: EventMap[P]): void } : never
修改后调用carWithListener.on时,只要传入合法的事件名字面量,TS就会自动推导出对应的回调参数类型,不需要手动标注val的类型。
内容的提问来源于stack exchange,提问作者Rajat Saxena
相关产品推荐
相关产品推荐

