【问题标题】:Subtyping arguments of functions with flowtype使用 flowtype 对函数的参数进行子类型化
【发布时间】:2017-12-16 13:30:31
【问题描述】:

我的应用程序中的几种类型很少有共同的属性。我将通用属性抽象为单独的类型。现在我想写一个函数来接受任何具有共同基类型的类型。

这几行比文字更能说明问题:

type Box = {
  width: number,
  height: number,
}

// is like Box + it has position
type PositionedBox = Box & {
  type: 'positionedBox',
  left: number,
  top: number,
}

// is like Box + it has colo
type ColorBox = Box & {
  type: 'colorBox',
  color: string,
}

const logSize = (obj: Box) => {
  console.log({ w: obj.width, h: obj.height });
};

const logPosition = (obj: PositionedBox) => {
  console.log({ l: obj.left, t: obj.top });
};

const logColor = (obj: ColorBox) => {
  console.log({color: obj.color});
};

// this function should accept any Box like type
const logBox = (obj: Box) => {
  logBox(obj);
  // $ERROR - obj Box has no type property
  // (make sense at some point, but how to avoid it?)
  if (obj.type === 'colorBox') logColor(obj);
  if (obj.type === 'positionedBox') logPosition(obj);
}

问题是:logBox() 函数声明应该是什么样子才能通过流类型检查。

【问题讨论】:

  • 你不能在比较值之前测试type属性的存在吗?或者只是在泛型类型中添加一个简单的'Box' 类型属性?
  • @Kaddath 检查type prop 的存在并没有太大变化我仍然会得到“在对象类型中找不到属性”。我在玩泛型类型,但我无法让它工作。如何做到这一点?
  • 向泛型添加类型Box 不能解决问题?

标签: javascript flowtype flow-typed


【解决方案1】:

这些错误是合法的,因为没有什么能阻止我将{width: 5, height: 5, type: 'colorBox'} 传递给logBox 函数,因为它是Box 的子类型。如果您真的想接受Box 的任何子类型,您将不得不处理后果,即检查type 字段不会为您提供任何其他属性的信息。

如果您只想允许Box 的特定子类型,那么您需要disjoint union。下面我将Box 重命名为BaseBox 并添加了一个单独的Box 类型,它是两个专用框的联合。这个例子通过了。

type BaseBox = {
  width: number,
  height: number,
}

// is like Box + it has position
type PositionedBox = BaseBox & {
  type: 'positionedBox',
  left: number,
  top: number,
}

// is like Box + it has colo
type ColorBox = BaseBox & {
  type: 'colorBox',
  color: string,
}

type Box = PositionedBox | ColorBox;

const logSize = (obj: Box) => {
  console.log({ w: obj.width, h: obj.height });
};

const logPosition = (obj: PositionedBox) => {
  console.log({ l: obj.left, t: obj.top });
};

const logColor = (obj: ColorBox) => {
  console.log({color: obj.color});
};

// this function should accept any Box like type
const logBox = (obj: Box) => {
  logBox(obj);
  // $ERROR - obj Box has no type property
  // (make sense at some point, but how to avoid it?)
  if (obj.type === 'colorBox') logColor(obj);
  if (obj.type === 'positionedBox') logPosition(obj);
}

【讨论】:

    猜你喜欢
    • 2021-04-23
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 2018-11-16
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多