对于具有不同参数对的通用函数,我正在努力使用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
任何想法如何声明这个功能?
或者这是一个愚蠢的想法,我会走向错误的方向?
任何更好的解决方案?
答案 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
,我只是将其称为区分您现有的类型和新的类型