如何让TypeScript识别过滤后的对象数组包含指定可选键?
问题
现有以下TypeScript代码:
interface Obj { requiredKey: string; optionalKey?: string; } type Arr = Array<Obj>; const arr: Arr = [ { requiredKey: "a", optionalKey: "b", }, { requiredKey: "c", }, ]; const filtered = arr.filter((obj) => obj.optionalKey);
怎么让TypeScript自动识别出filtered数组里的所有对象肯定有optionalKey?也就是让filtered的类型变成:
{ requiredKey: string; optionalKey: string; }[]
解决办法
1. 用类型谓词(Type Predicate)明确断言
TypeScript默认不会自动把filter的结果类型收窄,你需要给过滤回调加一个类型谓词,告诉编译器“当这个函数返回true时,当前对象属于某个更具体的类型”:
interface Obj { requiredKey: string; optionalKey?: string; } // 定义包含必填optionalKey的类型 type ObjWithOptional = { requiredKey: string; optionalKey: string; }; // 也可以用工具类型简化:type ObjWithOptional = Required<Pick<Obj, 'optionalKey'>> & Obj; const arr: Obj[] = [ { requiredKey: "a", optionalKey: "b" }, { requiredKey: "c" }, ]; // 类型谓词函数,严格判断属性是否存在 function hasOptionalKey(obj: Obj): obj is ObjWithOptional { return obj.optionalKey !== undefined; } const filtered = arr.filter(hasOptionalKey); // 此时filtered的类型就是ObjWithOptional[],完全符合需求
2. 内联写类型谓词(无需单独函数)
如果不想额外定义函数,直接把类型谓词写在filter回调里也行:
const filtered = arr.filter((obj): obj is Obj & { optionalKey: string } => { return obj.optionalKey !== undefined; });
3. 用NonNullable简化类型定义
利用TypeScript内置的NonNullable工具类型,快速排除属性的undefined情况:
type ObjWithOptional = Omit<Obj, 'optionalKey'> & { optionalKey: NonNullable<Obj['optionalKey']> }; const filtered = arr.filter((obj): obj is ObjWithOptional => { return obj.optionalKey !== undefined; });
为啥直接写obj.optionalKey不行?
因为obj.optionalKey作为布尔表达式时,TypeScript只能判断它是“真或假”,但没法自动关联到“这个属性一定存在”的类型断言——必须通过显式的类型谓词,把业务逻辑转化为编译器能理解的类型信息。
内容的提问来源于stack exchange,提问作者lelate
相关产品推荐
相关产品推荐

