如何用TypeScript映射类型生成关联type与payload的Reducer Action类型?
实现自动关联type与payload的Reducer Action类型
问题背景
现有函数集合:
const myFuncs = { appendFoo: (s: string) => `${s}FOO`, addFive: (n: number) => n + 5, }
需要创建一个Reducer Action类型,要求无需手动指定泛型,能自动根据type字段关联对应payload的类型。当前实现需要手动指定泛型参数,无法自动推断:
type MyAction<F extends keyof typeof myFuncs> = { type: F, payload: Parameters<typeof myFuncs[F]>[0] } // 必须手动指定泛型参数 const fooAction: MyAction<'appendFoo'> = { type: 'appendFoo', payload: 'bar' }
解决方案
可以通过映射类型生成联合类型的方式实现自动关联:
const myFuncs = { appendFoo: (s: string) => `${s}FOO`, addFive: (n: number) => n + 5, } // 生成自动关联的Action联合类型 type MyAction = { [K in keyof typeof myFuncs]: { type: K; payload: Parameters<typeof myFuncs[K]>[0]; } }[keyof typeof myFuncs];
用法示例
// 正确示例:TypeScript自动根据type推断payload类型 const fooAction: MyAction = { type: 'appendFoo', payload: 'bar' // 类型约束为string }; const addAction: MyAction = { type: 'addFive', payload: 1 // 类型约束为number }; // 错误示例:类型不匹配会触发TS报错 const invalidAction: MyAction = { type: 'appendFoo', payload: 1 // 此处TS会提示类型不兼容 };
原理说明
- 首先通过映射类型
{ [K in keyof typeof myFuncs]: ... },为myFuncs的每个键生成对应的Action结构,其中type为键名字面量,payload为对应函数的第一个参数类型; - 最后通过
[keyof typeof myFuncs]提取映射类型的所有值,形成一个联合类型; - 当声明
MyAction类型的变量时,TypeScript会根据type字段的字面量值,自动匹配联合类型中对应的分支,从而约束payload的类型。
内容的提问来源于stack exchange,提问作者usernamenumber
相关产品推荐
相关产品推荐

