TypeScript中使用Object.keys和reduce过滤对象空值的类型报错问题
解决TypeScript过滤对象空值时的类型错误
问题场景
有一个包含可选字段的对象类型Item,想要实现一个函数过滤掉对象中的空值(null/undefined),但编写代码后TypeScript抛出类型错误:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'.
No index signature with a parameter of type 'string' was found on type 'Item'.
原始代码:
type Item = { name?: string color?: string size?: string weight?: string } function filterNullItemValues(myItem: Item) { return Object.keys(myItem).reduce((acc, key) => { if (myItem[key]) { acc[key] = myItem[key] } return acc }, {}) }
错误原因
Object.keys()返回的类型是string[],而非keyof Item[]——TypeScript无法确保传入的myItem没有额外的非Item定义的属性,因此直接用string类型的key去索引Item类型的对象时,会触发类型不匹配的错误。
修复方案
方案一:类型断言+精确返回类型
通过类型断言将key转为keyof Item,同时定义过滤后的对象类型,让返回值类型更精准:
type Item = { name?: string color?: string size?: string weight?: string } // 定义过滤后非空属性的类型 type NonNullableItem = { [K in keyof Item as Item[K] extends NonNullable<Item[K]> ? K : never]: NonNullable<Item[K]> } function filterNullItemValues(myItem: Item): Partial<NonNullableItem> { return Object.keys(myItem).reduce((acc, key) => { const typedKey = key as keyof Item; const value = myItem[typedKey]; // 仅过滤null和undefined,若要过滤所有假值(如空字符串)可改为if (value) if (value != null) { acc[typedKey] = value as NonNullable<Item[typeof typedKey]>; } return acc; }, {} as Partial<NonNullableItem>); }
方案二:用Object.entries简化遍历
使用Object.entries()同时获取键和值,减少一次索引操作,同样通过类型断言解决类型问题:
type Item = { name?: string color?: string size?: string weight?: string } function filterNullItemValues(myItem: Item) { return Object.entries(myItem).reduce((acc, [key, value]) => { if (value != null) { acc[key as keyof Item] = value; } return acc; }, {} as Partial<{ [K in keyof Item]: NonNullable<Item[K]> }>); }
说明
value != null会同时排除null和undefined,如果需要过滤所有假值(比如空字符串""、数字0等),可以改为if (value)。Partial<NonNullableItem>表示返回的对象包含NonNullableItem的部分属性,符合过滤后可能缺少某些字段的实际情况。
内容的提问来源于stack exchange,提问作者Vic
相关产品推荐
相关产品推荐

