替换Flow类型中对象属性的类型

Replace the type of an object property in a Flow type

本文关键字:类型 属性 对象 Flow 替换      更新时间:2023-09-26

假设我们已经定义了一个非常简单的对象类型:

type A = {
  foo: string,
  bar: number,
  // ... many other properties
};

现在我们想定义这个类型的一个变体,只是用?string替换foo的类型:

type A2 = {
  foo: ?string,
  bar: number,
  // ... many other properties, with the same types as in A
};

如何做到这一点,而不必重新定义整个类型?

如果答案仅在用?T替换属性类型T的特定情况下有效,那就足够了,因为这是我最常见的问题。

我可以想到两个解决方案:

1)参数类型别名

type Parametric<T> = {
  foo: T,
  bar: number,
  // ... many other properties
};
type A = Parametric<string>;
type B = Parametric<?string>;

2)十字路口
type Base = {
  bar: number,
  // ... many other properties
};
type A = Base & { foo: string };
type B = Base & { foo: ?string };

我将使用精确类型的扩展运算符(在流程v0.42.0中引入)。

type A = {|
  foo: string,
  bar: number,
  // ... many other properties
|}
type A2 = {
   ...A,
   foo: ?string
}

注意:您需要为A使用精确的类型({| ... |}语法)。这是因为flow在传播时如何处理未密封(不是精确的)类型。

对于嵌套属性,您可以使用$PropertyType<T,>效用。

type Type1 = {
  prop1: string,
  prop2: {
    a?: string,
    b?: number,
  }
}
type Type2 = {
  ...Type1,
  prop2: {
    ...$PropertyType<Type1, "prop2">,
    c: boolean,
  }
}
const obj: Type2 = {
  prop1: "foo",
  prop2: {
    a: "foo",
    c: true,
  }
}
const {
  prop2: {
    a,
    b,
    c
  }
}: Type2 = obj;
if (c === true) {
  // do something
}

flow.org/try

相关文章: