TypeScript泛型参数推导报错:string|number不可赋值给never类型问题排查
问题原因
- 基类
State的抽象doAction方法定义的签名和子类实现不兼容,基类固定data为any类型,子类泛型实现的签名无法被TS正确识别 - 子类
doAction方法中多余声明的GData extends ActionData<GAction>泛型约束,会导致TS将联合类型的推导结果收窄为never,触发类型不匹配报错
修复代码
完整可运行的修复后代码如下:
abstract class Action<GData> { abstract isValid(data : GData): boolean static dostuff<GData>(action: Action<GData>, data : GData): boolean { return action.isValid(data); } } // 修改基类State的抽象方法签名,支持泛型推导 abstract class State<GAction extends Action<any>> { abstract doAction<T extends GAction>(action: T, data: ActionData<T>): State<GAction> } class NextAction extends Action<string> { isValid(data: string): boolean { return (data === "222") } } class LastAction extends Action<number> { isValid(data : number): boolean { return (data === 254); } } type AllStateActions = LastAction | NextAction type ActionData<S> = S extends Action<infer H> ? H : never; // 子类实现匹配基类签名即可 class OneState extends State<AllStateActions> { doAction<T extends AllStateActions>(action: T , data: ActionData<T>): OneState { if(!action.isValid(data)) { return this; } return this; } }
验证效果
调用时会自动推导正确的data类型:
const state = new OneState(); state.doAction(new NextAction(), "222"); // 类型校验通过 state.doAction(new LastAction(), 254); // 类型校验通过 state.doAction(new NextAction(), 123); // 触发类型错误,符合预期
内容的提问来源于stack exchange,提问作者Jacob Heath
相关产品推荐
相关产品推荐

