如何为基于AppState的TypeScript Action类型添加type属性?
解决TypeScript中Action类型添加type属性的报错问题
首先得说,你这个问题我之前也碰到过,核心是原来的Action类型定义思路偏了——你让它变成了一个必须包含所有AppState键+type的对象,但实际我们的action应该是「仅包含一个AppState键+对应type标识」的结构,这就导致类型不匹配,编译器自然报错了。
正确的思路是把Action定义成联合类型,每个联合成员对应「一个AppState的键+专属type」,这样既满足你给每个action加type的需求,又能保证类型安全。
解决方案1:基础版联合类型
直接生成包含单个状态键+type的联合类型,写法简洁且符合需求:
type AppState = { contentWidth: number mapLayers: string[] } // 核心逻辑:遍历AppState的每个键,生成对应的action类型,再取所有类型的联合 type Action = { [K in keyof AppState]: { type: string; [key in K]: AppState[K]; } }[keyof AppState];
这个Action类型等价于手动写的联合类型:
type Action = | { type: string; contentWidth: number } | { type: string; mapLayers: string[] };
现在你写action就完全合法了:
const appState: AppState = { contentWidth: 0, mapLayers: [], } // 合法:更新contentWidth的action const action1: Action = { type: 'DISPATCH_CONTENT_WIDTH', contentWidth: 200 }; // 合法:更新mapLayers的action const action2: Action = { type: 'DISPATCH_MAP_LAYERS', mapLayers: ['terrain', 'satellite'] };
解决方案2:更严谨的type自动推导(可选)
如果想让type和状态键严格绑定(比如contentWidth对应DISPATCH_CONTENT_WIDTH),可以用TS的字符串字面量转换自动生成规范的type值:
type Action = { [K in keyof AppState]: { // 自动将键名转为大写并拼接前缀,保证type的规范性 type: `DISPATCH_${Uppercase<string & K>}`; [key in K]: AppState[K]; } }[keyof AppState];
这时你写action时,type会有精准的自动提示,写错还会直接报错:
// 合法,type自动匹配状态键 const action: Action = { type: 'DISPATCH_CONTENT_WIDTH', contentWidth: 200 }; // 报错:type值不符合规范 const invalidAction: Action = { type: 'WRONG_TYPE', contentWidth: 200 };
为什么原来的写法会报错?
你之前写的:
type Action = { type: string [K in keyof AppState]: any }
这个类型要求必须同时包含type、contentWidth和mapLayers三个属性,但你的action只传了type和contentWidth,缺少mapLayers,所以TS编译器会抛出错误,这显然不符合你实际的action使用场景。
内容的提问来源于stack exchange,提问作者julesbou
相关产品推荐
相关产品推荐

