如何移除不符合TypeScript接口的对象多余属性?
问题解析与解决
TypeScript 接口仅在编译阶段做类型校验,运行时完全是原生 JavaScript 环境,所以它不会自动过滤对象的额外属性,也不会因为接口未定义的属性存在而抛出运行时错误。
为什么当前代码没报错?
TS 使用结构类型系统:只要目标对象包含接口声明的所有必填属性,就会被认为符合该接口类型,额外属性不会触发编译错误(除非开启额外属性检查的严格配置,或者使用精确类型)。你定义的Character接口只要求name和birthday,而 API 返回的对象确实包含这两个属性,所以编译阶段通过校验,但运行时对象的所有原始属性都会被保留。
如何只保留需要的属性?
你需要手动从返回的对象中提取目标属性,以下是几种可行方案:
方法1:手动解构提取
修改char函数,在获取数据后直接过滤出需要的属性:
import axios from 'axios' interface Character { name: string, birthday: string } const url = 'https://breakingbadapi.com/api/characters' async function char(): Promise<Character[]> { const res = await axios.get(url); return res.data.map(item => ({ name: item.name, birthday: item.birthday })); } (async function() { let characters: Character[] = await char(); console.log(characters[0]) // 现在只会包含name和birthday两个属性 })()
方法2:封装通用过滤函数
如果需要多次处理这类场景,可以写一个工具函数来提取指定属性:
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { const result = {} as Pick<T, K>; keys.forEach(key => { if (obj.hasOwnProperty(key)) { result[key] = obj[key]; } }); return result; } // 使用方式 async function char(): Promise<Character[]> { const res = await axios.get(url); return res.data.map(item => pick(item, ['name', 'birthday'])); }
方法3:编译阶段拦截多余属性(可选)
如果希望编译阶段就阻止未定义属性的赋值,可以在tsconfig.json中开启strictNullChecks和noImplicitAny,同时结合精确类型断言:
async function char(): Promise<Character[]> { const res = await axios.get(url); return res.data.map(item => ({ name: item.name, birthday: item.birthday } as const) as Character ); }
注意:这种方式仅在编译时校验,运行时仍需手动过滤才能真正移除多余属性。
内容的提问来源于stack exchange,提问作者relidon
相关产品推荐
相关产品推荐

