4 votes

Améliorer la vitesse de Typescript lorsqu'un type est un membre quelconque d'une carte ?

Par exemple, j'ai ces types :

class User extends Entity {}

class Post extends Entity {}

type Entities = {
  user: User,
  post: Post,
  // potentially hundreds more
};

type EntityType = 'user' | 'post' | ...;

Quand j'utilise Entities y EntityType en générique, cela ralentit sensiblement Typescript. Il faut plusieurs minutes rien que pour afficher les informations de type dans VS Code. J'ai des fonctions génériques comme :

function getEntityFromCache<T extends EntityType>(type: T, id: number): Entities[T] | null | undefined;

function getEntity<T extends EntityType>(type: T, id: number): Entities[T] | null {
  const cachedEntity = getEntityFromCache(type, id);
  if (cachedEntity !== undefined) {
    return cachedEntity;
  }
  ...
}

Si je comprends pourquoi c'est lent, c'est parce que Entities[T] est une union de toutes les valeurs de Entities c'est-à-dire User | Post | ... . TS ne gère pas bien les unions. Pour vérifier que le type de retour de cached est correcte, TS doit itérer à travers toutes les valeurs possibles de T . C'est-à-dire que si T = 'user' vérifiez que cachedEntity es Entities['user'] ; si T = 'post' vérifiez que cachedEntity es Entities['post'] et ainsi de suite. C'est lent car TS doit vérifier chaque valeur de l'union à chaque fois que j'ai un générique.

En outre, plutôt que de simplement comparer les valeurs des génériques ( 'user' === 'user' , 'post' === 'post' ), TS compare l'entité entière ( User === User , Post === Post ). Cela aggrave la situation car les entités sont compliquées.

Quels sont les moyens d'accélérer le processus ? Voici quelques idées que j'ai :

  1. Supprimez les génériques des fonctions intermédiaires et faites en sorte qu'elles renvoient le type d'entité de base, puis effectuez un cast de type. Par exemple function getEntityFromCache(type: T, id: number): Entity | null | undefined;

  2. D'une manière ou d'une autre, faites en sorte que TS compare la chaîne de caractères du type d'entité au lieu de comparer les entités entières.

4voto

Serhii Bilyk Points 9

Selon la page wiki de TypeScript Préférer les types de base aux syndicats Il est intéressant d'utiliser des sous-types, plutôt que des unions.

Cependant, ils ont aussi un coût. Chaque fois qu'un argument est passé à printSchedule, il doit être comparé à chaque élément de l'union. Pour une union à deux éléments, cela est trivial et peu coûteux. Cependant, si votre union comporte plus d'une douzaine d'éléments, cela peut poser de réels problèmes de vitesse de compilation. Par exemple, pour éliminer les membres redondants d'une union, les éléments doivent être comparés par paire, ce qui est quadratique. Ce type de vérification peut se produire lors de l'intersection de grandes unions, où l'intersection sur chaque membre de l'union peut donner lieu à des types énormes qui doivent ensuite être réduits. Une façon d'éviter cela est d'utiliser des sous-types, plutôt que des unions.

Exemple réduit de la documentation :

interface A {
  char: 'a' | 'b' | 'c' | 'd' | 'e';
}

interface B extends A {
  char: 'a' | 'b';
}

interface C extends A {
  char: 'd' | 'e';
}

declare function char(schedule: A): void;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X