【问题标题】:Typing composite type guards - infering/inheriting properties from type guard to its caller键入复合类型保护 - 从类型保护推断/继承属性到其调用者
【发布时间】:2021-03-24 03:51:58
【问题描述】:
type Bird = { fly: () => "fly" };
type Insect = { annoy: () => "annoy" };
type Dog = { beTheBest: () => "dogdogdog" };

type Animal = Bird | Insect | Dog;

const isBird = (animal: Animal): animal is Bird => {
  if ("fly" in animal) return true;
  return false;
};

const isInsect = (animal: Animal): animal is Insect => {
  if ("annoy" in animal) return true;
  return false;
};

const hasWings = (animal: Animal) => {
  if (isBird(animal)) return true;
  if (isInsect(animal)) return true;
  return false;
};

我将两个基本类型保护功能组合到复合 hasWings 保护中,但 TypeScript 并没有推断出它的类型保护特性 - 它只是将 typeof hasWings 推断为 (a: Animal) => boolean。有没有办法可以帮助 TS 推断或明确告诉 hasWingsisInsectisBird 类型保护的组合,而无需手动重新指定标准?

// Something like this would be useful to me:
const hasWings = (animal: Animal): ReturnType<typeof isBird> & ReturnType<typeof isInsect> => {
  if (isBird(animal)) return true;
  if (isInsect(animal)) return true;
  return false;
};

// Having to specify the whole list manually is not useful to me:
const hasWings = (animal: Animal): animal is Insect | Bird => {
  if (isBird(animal)) return true;
  if (isInsect(animal)) return true;
  return false;
};

【问题讨论】:

    标签: typescript typeguards


    【解决方案1】:

    您可以编写一个辅助函数来以这种方式组合类型保护。类型注释很拗口,但它确实有效:

    type TypeGuard<S, T extends S> = (x: S) => x is T;
    
    function typeGuardUnion<T extends TypeGuard<any, any>[]>(...fs: T): TypeGuard<
        T extends TypeGuard<infer S, any>[] ? S : never,
        T extends TypeGuard<any, infer U>[] ? U : never
    > {
        return ((x: any) => fs.some(f => f(x))) as any;
    }
    
    // TypeGuard<Animal, Bird | Insect>
    const hasWings = typeGuardUnion(isBird, isInsect);
    

    Playground Link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-01
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2019-05-16
      • 2016-04-18
      相关资源
      最近更新 更多