TypeScript switch语句报错Type 'string | number' not assignable to 'never'如何解决
错误原因
- TypeScript 中
Object.keys()方法的返回值类型被设计为string[],而非对象键的联合类型,这是 TS 出于类型安全的有意设计:因为 JS 中对象可以随时包含额外的运行时属性,TS 无法保证运行时的键一定和你定义的接口属性完全一致。 - 你的代码中
key的类型是string,TS 无法确认key属于BEStructure的合法属性,因此在赋值be[key] = fe[key]时,TS 会将be[key]的类型推断为所有属性类型的交集:string & number,而这个交集的结果就是never类型,自然不能接收string | number类型的值,因此抛出错误。
解决方法
提供3种常用的解决思路,可根据业务场景选择:
方法1:添加类型断言(最简单,适合属性较少的场景)
直接将key断言为keyof BEStructure,告知TS你已经确认key是合法属性:
static convertToBE(fe: Partial<FEStructure>): BEStructure { const be: BEStructure = {}; Object.keys(fe).forEach(key => { // 增加类型断言即可 const feKey = key as keyof BEStructure; switch (feKey) { case 'a': case 'b': // 其他业务逻辑 be[feKey] = fe[feKey] as never; break; default: be[feKey] = fe[feKey] as never; } }); return be; }
方法2:显式枚举属性列表(最安全,推荐)
直接指定要转换的属性数组,不使用Object.keys(),TS可以自动推断类型,不需要额外断言:
static convertToBE(fe: Partial<FEStructure>): BEStructure { const be: BEStructure = {}; // 显式列出所有要转换的属性 const keys: Array<keyof BEStructure> = ['a', 'b']; keys.forEach(key => { if (fe[key] === undefined) return; switch (key) { case 'a': case 'b': // 其他业务逻辑 be[key] = fe[key]; break; default: be[key] = fe[key]; } }); return be; }
方法3:封装通用转换函数(适合多个结构体转换的场景)
如果项目里有很多类似的前后端结构转换,可以封装一个泛型函数复用逻辑:
function convertStruct<From, To extends Record<string, any>>(from: Partial<From>, keys: Array<keyof To>): To { const to = {} as To; keys.forEach(key => { to[key] = from[key as unknown as keyof From] as never; }); return to; } // 调用时直接使用 static convertToBE(fe: Partial<FEStructure>): BEStructure { const be = convertStruct<FEStructure, BEStructure>(fe, ['a', 'b']); // 在这里添加每个属性的特殊业务逻辑即可 return be; }
内容的提问来源于stack exchange,提问作者Ethan Vu
相关产品推荐
相关产品推荐

