TypeScript中链式可选函数的参数类型推断问题
解决Slice函数中ctx类型自动推断问题
问题分析
你的代码中,泛型约束存在循环依赖:在定义T的约束时,返回值里的ctx.api类型直接引用了未完成推断的T,导致TypeScript无法解析ctx的具体类型,最终将其推断为any。
解决方案
通过拆分类型定义,利用TypeScript对循环条件类型的支持,让ctx.api的类型能从T中正确提取:
// 定义单个slice方法的类型:接受state和payload,返回新状态或带ctx的异步函数 type SliceFn<S, P, API> = (state: S, payload: P) => S | ((ctx: { api: API }) => Promise<void>); // 从slice配置T中提取api类型:每个api方法对应原方法的payload参数 type SliceAPI<T, S> = { [K in keyof T]: T[K] extends SliceFn<S, infer P, any> ? (payload: P) => void // 若需要api方法包含state,改为 (state: S, payload: P) => void : never; }; // 重构slice函数的泛型约束 export function slice< S extends Record<string, any>, T extends Record<keyof T, SliceFn<S, any, SliceAPI<T, S>>> >( config: T, { initialState }: { initialState: S }, ) { return {}; } // 测试示例 interface TestState { isTest: boolean; } const s = slice({ login: (state: TestState, param: number) => async (ctx) => { type T1 = typeof ctx.api; // 现在类型为 { login: (payload: number) => void; } // 若修改SliceAPI为包含state,则类型为 { login: (state: TestState, payload: number) => void; } }, }, { initialState: { isTest: true } });
说明
SliceFn:明确单个slice方法的结构,将ctx.api的类型作为泛型参数传入,避免直接在约束中引用未推断的T。SliceAPI:通过条件类型从T中提取每个方法的payload类型,生成对应的api方法签名。- 泛型约束调整:让
T的每个方法都关联SliceAPI<T, S>,形成合法的循环依赖,TypeScript会自动完成类型推断。
内容的提问来源于stack exchange,提问作者Andy Jessop
相关产品推荐
相关产品推荐

