Home > Enterprise >  How to improve typescript's performance in the following scenario
How to improve typescript's performance in the following scenario

Time:09-07

The code below is a chain of linked items with the type being progressively built up. Typescript quickly becomes unusable in handling this kind of type. What performance optimization can be implemented to improve how typescript handles this kind of type, without sacrificing functionality?

type LMerge<T1, T2> = {
  [k in keyof T1]: k extends keyof T2 ? T2[k] : T1[k]
}

type PossibleGenerics = {
  Output?: unknown
  Error?: unknown
  ResultResolverController?: unknown
  ErrorResolverController?: unknown
}

type Generics = Required<PossibleGenerics>

// T - is the generics from Generics that are set
// Defaults - are default Generics that are applied to children
type NodeItem<T extends Generics, Defaults extends Generics> = {

  // S - is a subset of generics from Generics that are set, including none: {}
  // NewDefaults - any changes to Defaults.
  <
    S extends PossibleGenerics = {}, // specify generics
    NewDefaults extends PossibleGenerics = {}, // specify any changes to the Defaults
    UpdatedDefaults extends Generics = LMerge<Defaults, NewDefaults>, // updated Defaults after changes
    Child extends Generics = LMerge<UpdatedDefaults, S>, // generics and Defaults applied
  >(): NodeItem<Child, UpdatedDefaults>
  NodeItem: T
}

const example = {} as NodeItem<
  {
    Output: string
    Error: string
    ResultResolverController: string
    ErrorResolverController: string
  },
  Generics
>
const exampleUsage1 = example<{ Output: number }, { Error: Error }>()
const exampleUsage2 = exampleUsage1<{ Output: number }>()
...
const exampleUsage21 = exampleUsage20<{ Output: number }>()  // Type instantiation is excessively deep and possibly infinite.(2589)

code

CodePudding user response:

You need to collapse LMerge as soon as it's created:

type LMerge<T1, T2> = {
  [k in keyof T1]: k extends keyof T2 ? T2[k] : T1[k]
} extends infer O ? { [K in keyof O]: O[K] } : never;

Now you force TypeScript to compute the result and store it in an object.

Playground

  • Related