如何过滤含两种类型的数组获取目标类型?规避类型转换问题
过滤联合类型数组仅保留UserType的解决方案
问题背景
你需要从包含UserType和AdminType的联合类型数组中筛选出仅含UserType的元素,直接访问el.user时触发TypeScript错误:Property 'user' does not exist on type 'UserType' | 'AdminType',原因是联合类型中AdminType没有user属性,TypeScript不允许跨类型访问非公共属性。
推荐方案:内联类型守卫+类型谓词
你不需要单独定义谓词函数,直接在filter回调中结合类型守卫和类型谓词,既能通过TypeScript检查,又能保证类型安全:
export type UserType = { user: string; data: string} export type AdminType = { admin: string; data: string } const usersAndAdminsArr = [{ admin: '2312', data: 'blabla' }, { admin: '33123', data: 'blabla' }, { user: '111', data: '' }]; const selected = { user: '111' }; // 假设selected为目标用户对象 // 筛选出符合条件的UserType元素 const filteredUsers = usersAndAdminsArr.filter((el): el is UserType => { // 先判断是否为UserType,再匹配目标user值 return 'user' in el && el.user === selected.user; });
这里'user' in el是TypeScript支持的类型守卫,能在编译时推断当前el为UserType,同时el is UserType作为类型谓词,让filter返回的数组类型被正确推断为UserType[],后续代码可以安全访问user属性。
临时应急方案:类型断言(谨慎使用)
如果暂时无法使用类型守卫,可通过类型断言绕过检查,但这会失去TypeScript的类型保护,仅适合临时场景:
// 不推荐:可能导致运行时访问undefined的风险 const filteredUsers = (usersAndAdminsArr as UserType[]).filter(el => el.user === selected.user);
这种方式的问题是,数组中的AdminType元素会被强制断言为UserType,运行时访问el.user会得到undefined,可能引发后续逻辑错误。
替代方案:拆分过滤逻辑
先筛选出所有UserType元素,再匹配目标用户:
// 第一步:筛选所有UserType元素 const allUsers = usersAndAdminsArr.filter((el): el is UserType => 'user' in el); // 第二步:匹配指定user值 const filteredUsers = allUsers.filter(el => el.user === selected.user);
这种方式逻辑更清晰,也能保证每一步的类型安全。
核心说明
- TypeScript对联合类型的属性访问有严格限制,只有所有类型共有的属性才能直接访问
'key' in object是最可靠的运行时类型检查方式,比判断object.key !== undefined更准确(避免属性存在但值为undefined的误判)- 类型谓词(
el is UserType)能让TypeScript自动推断过滤后的数组类型,是类型安全的首选方案
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

