如何在TypeScript中编写判断多值均已定义的类型守卫函数
如何编写支持多值的TypeScript类型守卫函数,判断所有参数均非undefined
你可以通过泛型元组类型和映射类型实现这个通用的多值类型守卫函数,让TypeScript能够准确推断出所有参数在判断后均为非undefined类型。
最终实现代码
function allValuesAreDefined<T extends readonly unknown[]>( ...values: T ): values is { [K in keyof T]: Exclude<T[K], undefined> } { return values.every(value => value !== undefined); }
类型定义解析
- 泛型
T:约束为readonly unknown[],用于捕获传入参数的元组类型(保留每个参数的具体类型信息)。 - 返回值类型谓词:
values is { [K in keyof T]: Exclude<T[K], undefined> },通过映射遍历元组的每个索引,将对应类型中的undefined排除,从而告诉TypeScript:当函数返回true时,所有参数的类型都已被收窄为非undefined的版本。
使用示例
// 示例依赖的类型和函数声明 type LocalDate = { now: () => LocalDate; minusYears: (years: number) => LocalDate; isBefore: (date: LocalDate) => boolean; }; type Car = { manufacturer: { name: string } }; declare function getName(): string | undefined; declare function getBirthDate(): LocalDate | undefined; declare function getCar(): Car | undefined; // 实际使用场景 const name: string | undefined = getName(); const birthdate: LocalDate | undefined = getBirthDate(); const car: Car | undefined = getCar(); if (allValuesAreDefined(name, birthdate, car)) { // TypeScript自动推断:name是string,birthdate是LocalDate,car是Car console.log(name.concat(' you suck, no sorry, actually I do')); console.log(car.manufacturer.name); console.log( LocalDate.now().minusYears(18).isBefore(birthdate) ? 'Sorry dude you are underage' : 'Welcome to...' ); }
这个实现完全通用,支持任意数量、任意类型的参数组合,只要参数是X | undefined的形式,就能通过该函数完成批量类型收窄。
内容的提问来源于stack exchange,提问作者t-MURO
相关产品推荐
相关产品推荐

