CALICAWESOME
CALICAWESOME

Reputation: 55

Construct a union type from an object type

I have a type that looks like this:

type MessageTypes = {
  foo: { bar: string };
  baz: { qux: string, quux: string };
  corge: { grault: number };
};

I'd like to define a type that gives me something like:

| {
  op: 'foo';
  data: { bar: string };
}
| {
  op: 'baz';
  data: { qux: string, quux: string };
}
| {
  op: 'corge';
  data: { grault: number };
}

The closest I've come so far is this:

type KnownMessage = {
  [T in keyof MessageTypes]: { op: T; data: MessageTypes[T] };
};

However, I don't care about the keys from this type, only the values.

What's the best way to define my special union type using MessageTypes?

Upvotes: 1

Views: 33

Answers (1)

tenshi
tenshi

Reputation: 26327

Very close; just get a union of all the values like this:

type KnownMessage = {
  [T in keyof MessageTypes]: { op: T; data: MessageTypes[T] };
}[keyof MessageTypes];

It works because this:

{
    foo: 1,
    bar: 2,
}["foo" | "bar"]

results in a union of the values 1 and 2 => 1 | 2

Upvotes: 1

Related Questions