【问题标题】:Replace the type of an object property in a Flow type替换 Flow 类型中对象属性的类型
【发布时间】:2021-03-02 03:53:46
【问题描述】:

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

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

现在我们要定义这种类型的变体,只需将foo 的类型替换为?string

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

如何在不必重新定义整个类型的情况下做到这一点?

如果答案仅适用于将属性类型T 替换为?T 的特定情况就足够了,因为这是我最常遇到的问题。

【问题讨论】:

    标签: javascript flowtype


    【解决方案1】:

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

    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 };
    

    【讨论】:

    • 解决方案 1 非常适合一个参数(这是我要求的,所以我将其标记为已接受的答案)。但是,如果要修改的属性数量增加,它可能会变得很麻烦。
    • 是否不可能在不修改原始类型的情况下从类型中删除属性(可能通过某些 $Xxxx 指令)?
    • $Diff,但你最终会得到不同的行为:Flowtype/try
    • 事实上,我用 $Diff 做了很多试验,但不知何故无法找到解决方案。我也试试,非常感谢!
    • $Diff 解决方案(@gcanti 的评论)中,不仅允许减去的属性成为undefined,而且所有其他属性也是如此!这是故意的吗?
    【解决方案2】:

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

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

    注意:You need to use an exact type for A{| ... |} 语法)。这是因为流在传播时如何处理未密封(不精确)的类型。

    【讨论】:

      【解决方案3】:

      对于嵌套属性,您可以使用$PropertyType<T, k> 实用程序。

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-16
        • 2019-04-03
        • 2018-06-28
        • 2012-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多