如何使用TypeScript类型谓词实现不可赋值类型的数组过滤?
undefined状态过滤数组并转换类型 我需要根据数组元素中特定属性的undefined状态过滤数组,尝试用类型谓词指定filter方法的返回类型,但遇到了类型不兼容的问题:数组元素属于包含必填属性的RequiredModel类型,而目标类型OptionalModel中该属性是可选的。
示例代码:
interface OptionalModel { prop?: string; otherProp: number; } interface RequiredModel { prop: string | undefined; otherProp: number | undefined; } const array: RequiredModel[] = []; // 尝试过滤并转换为OptionalModel[],但报错 const filterKO = array.filter((value): value is OptionalModel => typeof value.otherProp !== 'undefined'); // ✗
TypeScript给出的错误提示:
A type predicate's type must be assignable to its parameter's type.
Type 'OptionalModel' is not assignable to type 'RequiredModel'.
Property 'prop' is optional in type 'OptionalModel' but required in type 'RequiredModel'.(2677)
解决方案
方法1:类型断言直接转换
过滤后数组元素的otherProp必然是number,而RequiredModel中的prop: string | undefined和OptionalModel的prop?: string本质类型等价(可选属性的底层类型就是T | undefined),因此可以直接用类型断言:
const filtered = array.filter(value => typeof value.otherProp !== 'undefined') as OptionalModel[];
方法2:先通过合法类型谓词收窄,再转换
定义一个RequiredModel的子类型,确保otherProp为已定义状态,用合法的类型谓词过滤后再转换为目标类型:
// 定义RequiredModel的子类型,确保otherProp是number type ValidRequiredModel = RequiredModel & { otherProp: number }; const filtered = array.filter((value): value is ValidRequiredModel => typeof value.otherProp !== 'undefined' ) as OptionalModel[];
方法3:转换结构后断言(更严谨的场景)
如果需要明确剥离属性的undefined语义,可以在过滤后通过map转换结构,严格匹配OptionalModel的可选属性语义(属性不存在而非存在但为undefined):
const filtered = array .filter(value => typeof value.otherProp !== 'undefined') .map(value => ({ otherProp: value.otherProp, ...(value.prop !== undefined ? { prop: value.prop } : {}) })) as OptionalModel[];
内容的提问来源于stack exchange,提问作者Neluji

