带Typescript的可变类型防护

时间:2018-10-16 22:22:34

标签: typescript

我正在尝试创建一个高阶函数,该函数允许我创建一个通过类型保护来确认类型的函数。

type Shape = Circle | Triangle | Rectangle
enum Type { Circle, Triangle, Rectangle }

interface Circle {
  type: Type.Circle;
  diameter: number;
}

interface Triangle {
  type: Type.Triangle;
  width: number;
}

interface Rectangle {
  type: Type.Rectangle;
  width: number;
  height: number;
}

const isShape = (condition: Type) => (shape: Shape): shape is ? => shape.type == condition;

const isCircle = isShape(Type.Circle);

在上面的示例中,我希望isCircle函数返回类型是否为Circle?是一个占位符,因为我无法使用它。

2 个答案:

答案 0 :(得分:2)

要实现目标,这是isShape函数的外观:

const isShape = <T extends Shape>(condition: Type) => {
  return function(shape: T): shape is T {
    return shape.type == condition;
  };
};

const isCircle = isShape<Circle>(Type.Circle);

答案 1 :(得分:2)

您需要为TypeScript提供一种直接方法来找出与给定的Shape关联的Type。一种实现方法是显式提供两者之间的映射,然后可以将其用于替换Shape的定义。因此,例如:

// Instead of this:
// type Shape = Circle | Triangle | Rectangle

// Use this:
type TypeToShape = {
  [Type.Circle]: Circle,
  [Type.Triangle]: Triangle,
  [Type.Rectangle]: Rectangle,
}

// Circle | Triangle | Rectangle
type Shape = TypeToShape[keyof TypeToShape];

然后,给定特定的Type,很容易将其映射到与其关联的Shape

// Use the type map to tell typescript what shape goes with the Type K:
const isShape = <K extends Type>(condition: K) => (shape: Shape): shape is TypeToShapeMap[K] => shape.type == condition;

const isCircle = isShape(Type.Circle); // return type: shape is Circle
const isTriangle = isShape(Type.Triangle) // return type: shape is Triangle