1

As in the title. "Resolving" as in converting { a: string } & { b: string } to { a: string, b: string }.

This is @jcalz's one, from his answer to "How can I see the full expanded contract of a Typescript type?":

type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;

And this is his summary:

Those use conditional type inference to "copy" a type T into a new type variable O and then an identity-like mapped type which iterates through the copied type's properties.

The conditional type inference is conceptually a no-op, but it's used to distribute union types and to force the compiler to evaluate the "true" branch of the conditional (if you redefine Expand<T> without it, sometimes the compiler will just output the mapped type {[K in keyof RelevantType]: RelevantType[K]}, which is not what you want to see).

And this is the one Gabriel Vergnaud uses in his Type-Level Typescript workshop:

/**
 * Compute is a helper converting intersections of objects into
 * flat, plain object types.
 */
type Compute<T> = { [K in keyof T]: T[K] } & unknown

As to the methods of the types, @jcalz's one uses the conditional type inference to force the evaluation of the type, while Gabriel's one uses an intersection with unknown.

EDIT

To clarify:
What are the technical differences in the output of these two methods? And are there any cases where their output will differ?

Bonus points for info on things like performance.

Darryl Noakes
  • 2,207
  • 1
  • 9
  • 27

0 Answers0