如何在TypeScript中为对象使用动态键并解决类型错误?
TypeScript类型错误处理:精准约束对象键与值的类型
问题描述
写了下面这段TypeScript代码:
interface Cat { color: string, weight: number, cute: Boolean, // 毕竟所有猫都可爱! } export const doSomething = ( cat: Array<Cat| null>, index: number, key: keyof typeof cat, payload: string | number | Boolean ) => { .... cat[key] = payload .... }
结果报了错:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
知道是TypeScript把key当成任意字符串了,不是Cat里的color、weight、cute这三个键。改成key: keyof Cat后还是报错:
cat[key] = payload
报错翻译过来是:
类型“string | number | Boolean”不能赋值给类型“string & number & Boolean”
解决步骤
1. 先修正对象访问逻辑
首先你搞错了修改对象的方式:参数cat是猫的数组,你要改的是数组里指定索引的那只猫,不是数组本身。先通过index拿到目标猫:
const targetCat = cat[index]; if (targetCat) { // 先判断是不是null,防止空值报错 targetCat[key] = payload; }
2. 用泛型绑定键和值的类型
直接用keyof Cat和string | number | Boolean会类型不兼容,因为TS没法确定当前key对应的值到底是哪种类型。用泛型就能把键和对应值的类型绑定起来:
interface Cat { color: string, weight: number, cute: boolean, // 注意:TS里推荐用小写boolean原生类型,大写Boolean是包装对象,尽量别用 } export const doSomething = <K extends keyof Cat>( cats: Array<Cat | null>, index: number, key: K, payload: Cat[K] // 这里自动匹配key对应的属性类型 ) => { const targetCat = cats[index]; if (targetCat) { targetCat[key] = payload; } }
核心要点
- 泛型
K extends keyof Cat直接把key锁死在Cat的三个属性里,不会再出现任意字符串的问题 payload: Cat[K]确保传的参数类型和当前key的属性类型完全匹配,比如传key="weight"时,payload必须是number,杜绝类型不匹配的错误- 加
if (targetCat)判断,避免数组里有null时的运行时崩溃 - 把
Boolean换成boolean是TS的最佳实践,减少不必要的类型歧义
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

