具有不同参数的Flowtype泛型函数

时间:2018-06-06 13:30:33

标签: flowtype

对于具有不同参数对的通用函数,我正在努力使用flowtype声明。

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

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

任何想法如何声明这个功能?

或者这是一个愚蠢的想法,我会走向错误的方向?

任何更好的解决方案?

1 个答案:

答案 0 :(得分:0)

创建一个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!

如果需要,您可以创建一个返回MessageFactory的{​​{1}}类型。如果需要控制对象上的GenericMessage<T, P>属性,还可以创建EVENT类型参数。

(您不需要将其称为event,我只是将其称为区分您现有的类型和新的类型