如何从TypeScript类型守卫函数提取类型并自动推断泛型参数?
解决方案:从类型守卫自动推断泛型类型
TypeScript没有内置TypeguardType工具类型,但你可以自己实现一个,用来提取类型守卫函数中守卫的目标类型,进而让函数自动推断返回值类型,无需手动指定泛型参数。
步骤1:实现TypeguardType工具类型
这个工具类型会提取类型守卫函数返回值中is关键字后的目标类型:
type TypeguardType<T extends (x: any) => x is any> = T extends (x: any) => x is infer U ? U : never;
步骤2:改造findAnimal函数
调整泛型参数的定义,让它从传入的matcher类型守卫函数中自动推断目标类型:
function findAnimal<TMatcher extends (animal: any) => animal is any>( animals: Array<any>, matcher: TMatcher ): TypeguardType<TMatcher> | undefined { return animals.find(matcher) as TypeguardType<TMatcher>; }
或者用更简洁的写法,直接将泛型与类型守卫绑定:
function findAnimal<TAnimal>( animals: Array<any>, matcher: (animal: any) => animal is TAnimal ): TAnimal | undefined { return animals.find(matcher); }
完整使用示例
class Dog { bark() { } } class Cat { meow() { } } function isDog(animal: any): animal is Dog { return !!animal.bark; } function isCat(animal: any): animal is Cat { return !!animal.meow; } const animals = [new Dog(), new Cat()]; // 无需手动指定泛型,TypeScript自动推断类型 const dog2 = findAnimal(animals, isDog); // dog2类型为Dog | undefined const cat2 = findAnimal(animals, isCat); // cat2类型为Cat | undefined // 调用方法时会有准确的类型提示 dog2?.bark(); cat2?.meow();
说明
- 第二种简洁写法直接将泛型
TAnimal与类型守卫函数的返回类型绑定,TypeScript会自动从matcher的类型守卫中推断出TAnimal的具体类型,无需额外工具类型。 - 返回值类型加上
undefined是因为Array.find()可能找不到匹配项,符合TypeScript的严格类型检查规范。
内容的提问来源于stack exchange,提问作者TwitchBronBron
相关产品推荐
相关产品推荐

