I have a union type:
type Msg = { type: 'banana', value: number[] } | { type: 'apple' };
now i would like to create a function that creates such a Fruit type, with two arguments and takes a generic for the Msg
:
const createMsg = <M extends { type: string }>(type: M["type"], value?: M["value"]) => ({ type, value });
The value
argument of the function should be linked to the type of value
of the union type, and if it's not defined, the param should be optional. I would like to be able to call it in two ways:
createMsg('banana', [1, 2, 3]);
createMsg('apple');
All my current solutions so far forced me to provide a second argument undefined
for the 'apple'
union-type.
CodePudding user response:
You can't have conditional parameters, the most simple way to do this is to pass a Msg
to createMsg
:
const createMsg = (msg: Msg): Msg => (msg)
const a = createMsg({ type: "apple" })
const b = createMsg({ type: "banana", value: [1,2,3] })
CodePudding user response:
Another method would be to use overloads (although this can get finicky with many more constituents):
type Type = { type: "foo"; value: number[] } | { type: "bar" };
function createMessage(type: "foo", value: number[]): Type;
function createMessage(type: "bar"): Type;
function createMessage(type: "foo" | "bar", value?: number[]) {
if (value) return { type, value };
return { type };
}