如何让TypeScript条件类型不匹配any类型?
问题描述
使用TypeScript条件类型过滤对象中类型为{visible: boolean}的字段时,any类型的字段(如示例中的value1)被错误地包含在结果中,需要修改类型定义以排除这类字段。
原始代码:
export type Column = { value1: any; value2: string; value3: { visible: boolean }, value4: { visible: boolean } } type VisibleFieldOnColumn<T> = { [K in keyof T as NonNullable<T[K]> extends { visible: boolean } ? K : never]: T[K]; }; type Test = VisibleFieldOnColumn<Column>; // Test 会包含 value1: any,不符合预期 const v:Test = { value1:'', // 需要移除该字段 value3:{visible:false}, value4:{visible:false} }
解决方案
修改条件类型,在判断字段类型是否匹配{visible: boolean}的同时,排除any类型的字段。核心思路是利用TypeScript中unknown extends any为true、而unknown extends { visible: boolean }为false的特性,区分any和真正的目标类型。
简洁实现
type VisibleFieldOnColumn<T> = { [K in keyof T as NonNullable<T[K]> extends { visible: boolean } ? (unknown extends NonNullable<T[K]> ? never : K) : never ]: T[K]; };
可读性更强的实现(带辅助类型)
// 辅助类型:判断目标类型是否为 any type IsAny<T> = unknown extends T ? (T extends unknown ? true : false) : false; type VisibleFieldOnColumn<T> = { [K in keyof T as NonNullable<T[K]> extends { visible: boolean } ? (IsAny<NonNullable<T[K]>> extends true ? never : K) : never ]: T[K]; };
效果验证
修改后,Test类型将只包含value3和value4,value1被正确排除:
type Test = VisibleFieldOnColumn<Column>; // Test = { value3: { visible: boolean }; value4: { visible: boolean } } // 此时以下代码会报错,符合预期 const v:Test = { value1:'', // 类型错误:属性value1不在Test类型中 value3:{visible:false}, value4:{visible:false} }
关键逻辑说明
- TypeScript中
any类型与任何类型的extends判断都会返回true,这是原始代码中value1被误匹配的核心原因。 - 通过
unknown extends NonNullable<T[K]>可以精准判断目标类型是否为any(仅any会让该表达式为true),如果是则返回never,从而排除对应字段。 - 辅助类型
IsAny封装了判断逻辑,让代码意图更清晰,便于后续维护。
内容的提问来源于stack exchange,提问作者Mr.Trieu
相关产品推荐
相关产品推荐

