typescript - Ce să faci în legătură cu inferența de tip TS extrem de lentă pentru IntelliSense cu tipuri recursive și închise în altele?


Încerc să creez tipuri pentru o versiune normalizată a tipurilor JSON-LD schema.org. Acestea sunt furnizate de pachetul schema-dts. Acesta este doar un exemplu de pachet care exportă multe tipuri care, în plus, sunt profund înnădite și interconectate între ele. Prin urmare, când spui ceva de genul

import type * as schemaOrg from 'schema-dts';
const restaurant: schemaOrg.Restaurant = {
 // ...
}

și apoi folosind IntelliSense, de exemplu pentru a afișa proprietățile în restaurant, deja ia mai mult timp decât de obicei, dar doar câteva milisecunde, deci asta nu reprezintă o problemă.

Totuși, încerc să creez o versiune ușor normalizată a unor astfel de tipuri, și le-am tastat după cum urmează:

type PrimitiveValue = undefined | null | boolean | number | string;
type Flattened<A> = A extends (infer E)[] ? Flattened<E> : A;
type IdReference = {'@id': string;};
type PreprocessedSchemaOrgValue<TValue> = Exclude<TValue, IdReference | schemaOrg.Role>;
type NormalizedSchemaOrgValue<T> =
  T extends any ? // This is for associative distribution
    T extends schemaOrg.Role ? never :
    T extends schemaOrg.Boolean ? boolean :
    T extends `${number}` ? number :
    T extends ((infer E)[] | readonly (infer E)[]) ? Flattened<NormalizedSchemaOrgValue<E>>[] :
    T extends {'@type': string | string[]} ? {
      [k in keyof T]: k extends '@id' |'@type' ? T[k] :
        T[k] extends PrimitiveValue
          ? Exclude<T[k], undefined>[] | undefined
          : Exclude<NormalizedSchemaOrgValue<T[k]>, undefined>[] | undefined // This recursion probably causes the problem
      ;
    } :
    T extends IdReference ? never :
    PreprocessedSchemaOrgValue<T>
  : never
;

Observă recursiunea. Funcționează în principiu, dar acum când încerc

const restaurant: NormalizedSchemaOrgValue<schemaOrg.Restaurant> = {
  // ...
};

utilizarea IntelliSense (în VSCode) aici durează excesiv de mult (poate 10-20 de secunde). Poți să testezi singur în playground-ul TS. Acest lucru nu este prea surprinzător datorită recursivității în combinație cu imbricarea.

Se poate face ceva în legătură cu asta?

Răspuns #1

Căci motivul pentru care acest lucru funcționează îmi scapă, dar excluderea string înainte de normalizarea schemei pare să îmbunătățească drastic viteza:

// zoom!
const restaurant: NormalizedSchemaOrgValue<Exclude<schemaOrg.Restaurant, string>> = {
  
};

Teren de joacă