如何基于_stepResult返回类型推断message参数?改写为()=>T可运行
TypeScript基于返回值推断参数类型的问题
我想要让handleFn中_stepResultFn的message参数类型,能根据_stepResult的返回值自动推断出来。但目前只有把_stepResult的类型定义改成() => T形式时,类型推断才正常工作,以下是我的代码:
type Txt = { type: "message"; text: string; }; type Image = { type: "image"; url: string; }; type TextMessage = { type: 'message'; text: string; }; type ImageMessage = { type: 'image', description: string; url: string; }; type StepMap = { message: [Txt, TextMessage]; image: [Image, ImageMessage]; }; const handleFn = <T extends keyof StepMap>( name: string, _stepResult: () => StepMap[T][1], _stepResultFn: (message: StepMap[T][0]) => StepMap[T][0] ) => {}; const messageStep = handleFn( 'start', () => { return { type: 'message', text: '123' }; }, ({ type, text }) => { return { text, type }; } ); const imageStep = handleFn( 'image_step', () => { return { type: 'image', description: 'img description', url: 'test.nl' } }, ({ type, url }) => { return { url, type }; } );
问题原因
原写法中,T被约束为keyof StepMap,但TypeScript无法从_stepResult的返回值反向推导T的具体值——因为StepMap[T][1]是依赖T的类型,类型推断方向不匹配,导致_stepResultFn的参数类型无法正确关联。
解决方案
调整泛型定义逻辑,让handleFn直接从_stepResult的返回类型R入手,通过辅助类型从StepMap中映射出对应的输入类型:
type Txt = { type: "message"; text: string; }; type Image = { type: "image"; url: string; }; type TextMessage = { type: 'message'; text: string; }; type ImageMessage = { type: 'image', description: string; url: string; }; type StepMap = { message: [Txt, TextMessage]; image: [Image, ImageMessage]; }; // 辅助类型:从返回类型R匹配对应的输入类型 type InputFromResult<R> = { [K in keyof StepMap]: StepMap[K][1] extends R ? StepMap[K][0] : never }[keyof StepMap]; const handleFn = <R extends StepMap[keyof StepMap][1]>( name: string, _stepResult: () => R, _stepResultFn: (message: InputFromResult<R>) => InputFromResult<R> ) => {}; const messageStep = handleFn( 'start', () => { return { type: 'message', text: '123' }; }, ({ type, text }) => { // 参数自动推断为Txt类型 return { text, type }; } ); const imageStep = handleFn( 'image_step', () => { return { type: 'image', description: 'img description', url: 'test.nl' } }, ({ type, url }) => { // 参数自动推断为Image类型 return { url, type }; } );
这种写法让TypeScript从_stepResult的返回值R出发,通过InputFromResult类型找到StepMap中对应的输入类型,实现自动推断。你提到的将_stepResult改为() => T的思路,本质也是让泛型从返回值入手,和上述方案逻辑一致。
内容的提问来源于stack exchange,提问作者Jarno van Rhijn
相关产品推荐
相关产品推荐

