【问题标题】:Flowtype generic function with different parameters具有不同参数的 Flowtype 泛型函数
【发布时间】:2018-11-16 05:16:29
【问题描述】:

我正在为具有不同参数对的通用函数的流类型声明而苦苦挣扎。

我的目标是有一个函数,它根据输入参数返回某个联合类型的对象。 我有大量要输入的消息(在这个例子中我只使用了两个)

type Message1 = {
  event: 'UI',
  type: 'receive',
  payload: boolean
}

type Message2 ={
  event: 'UI',
  type: 'send',
  payload: {
    foo: boolean;
    bar: string;
  }
}

type MessageFactory<T> = (type: $PropertyType<T, 'type'>, payload: $PropertyType<T, 'payload'>) => T;

export const factory: MessageFactory<Message1> = (type, payload) => {
    return {
      event: 'UI',
      type,
      payload
    }
}

factory('receive', true);
// factory('send', { foo: true, bar: "bar" });

当我改变时

MessageFactory<Message1> 

MessageFactory<Message1 | Message2>

会报错

Could not decide which case to select. Since case 1 [1] may work but if it doesn't case 2 [2] looks promising too. To fix add a type annotation to `payload` [3] or to `type` [4]

你可以联系它here

知道如何声明这个函数吗?

或者这是愚蠢的想法,我走错了方向?

有更好的解决方案吗?

【问题讨论】:

    标签: flowtype


    【解决方案1】:

    使用所需属性(类型和有效负载)的类型参数创建GenericMessage,然后让您的工厂返回GenericMessage

    (Try)

    type GenericMessage<TYPE: string, PAYLOAD> = {
      event: 'UI',
      type: TYPE,
      payload: PAYLOAD
    }
    
    const factory = <T: string, P>(type: T, payload: P): GenericMessage<T, P> => {
        return {
          event: 'UI',
          type,
          payload
        }
    }
    
    const test1 = factory('receive', true);
    const test2 = factory('send', { foo: true, bar: "bar" });
    
    // Let's check the new type against Message1 and Message2:
    type Message1 = {
      event: 'UI',
      type: 'receive',
      payload: boolean
    }
    
    type Message2 ={
      event: 'UI',
      type: 'send',
      payload: {
        foo: boolean;
        bar: string;
      }
    }
    
    // Type assertions
    (test1: Message1);
    (test2: Message2);
    (test1: Message2); // Error!
    

    如果需要,您可以创建一个返回 GenericMessage&lt;T, P&gt;MessageFactory 类型。如果需要控制对象的event属性,也可以创建EVENT类型参数。

    (你不需要叫它GenericMessage,我只是为了区分你现有的类型和这个新的类型)

    【讨论】:

    • 嗨@James,感谢您的回答。这不是我正在寻找的解决方案,因为如果您跳过测试类型断言,当您将不正确的参数对放入此函数时,流程不会引发任何错误。我宁愿在不测试断言的情况下得到错误
    • 在这种情况下,您可能会发现为函数编写多个类型定义很有帮助。查看 getElementsByTagName 的 lib defs in flow (lib/dom.js) 以查看此示例。获得所有声明后,将factory 函数设置为您使用declare function 声明的函数的类型。可能有更好的方法可以做到这一点,但这应该可行。如果您尝试后无法弄清楚,请发表其他评论。
    • 快速示例:flow.org/try/…
    • (如果你弄清楚了,你可以回答你自己的问题)
    猜你喜欢
    • 2022-01-04
    • 2019-03-21
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 2018-02-18
    • 1970-01-01
    相关资源
    最近更新 更多