TypeScript泛型对象类型下方法键推断失效问题
问题:TypeScript泛型约束下mockHookDefault的类型不兼容错误
我正在开发一个Mock工具,定义了如下核心方法,接收对象、对象上的函数键,以及输入输出映射记录:
function mockHook< OBJECT extends Record<string, any>, METHOD_NAME extends MethodKeys<OBJECT>, METHOD extends AnyFunction = OBJECT[METHOD_NAME], >( obj: OBJECT, methodName: METHOD_NAME, mockedConditions: Map<Parameters<METHOD>, Partial<ReturnType<METHOD>>> )
配套的辅助类型定义:
type AnyFunction = (...args: any[]) => any; /** * 提取T中键为字符串且值为方法的条目类型 */ type MethodKeys<T> = { [K in keyof T]: K extends string ? (T[K] extends AnyFunction ? K : never) : never; }[keyof T];
需求与尝试实现
我有个常见场景:对象包含default键,因此想要创建辅助方法mockHookDefault,固定使用'default'作为方法名并保证类型约束。我的尝试实现如下:
export function mockHookDefault< OBJECT extends { default: AnyFunction }, METHOD extends OBJECT['default'] = OBJECT['default'], >(obj: OBJECT, mockedConditions: Map<Parameters<METHOD>, Partial<ReturnType<METHOD>>>) { return mockHook(obj, 'default', mockedConditions); }
遇到的错误
调用mockHook时出现类型错误:
TS2345: Argument of type string is not assignable to parameter of type MethodKeys<OBJECT>
奇怪的类型现象
在mockHookDefault内部执行以下代码时:
const a: MethodKeys<OBJECT> = 'default'; const b: MethodKeys<{ default: () => {} }> = 'default';
a会抛出TS2322: Type string is not assignable to type MethodKeys错误,但b完全正常。在我看来这两种类型逻辑上是一致的,为什么TypeScript会有不同的处理?
问题
- 为什么TypeScript不允许将
'default'赋值给MethodKeys<OBJECT>类型的变量? - 能否不使用
as MethodKeys<OBJECT>类型断言来修复这个问题?
内容的提问来源于stack exchange,提问作者Yftach
相关产品推荐
相关产品推荐

