Migrations

Migration vers la fonction inject

La fonction inject d'Angular offre des types plus précis et une meilleure compatibilité avec les décorateurs standards que l'injection par constructeur.

Ce schematic convertit l'injection par constructeur de vos classes pour utiliser la fonction inject à la place.

Lancez le schematic avec la commande suivante :

ng generate @angular/core:inject

Avant

import {Component, Inject, Optional} from '@angular/core';
import {MyService} from './service';
import {DI_TOKEN} from './token';

@Component({template: ''})
export class MyComp {
  constructor(
    private service: MyService,
    @Inject(DI_TOKEN) @Optional() readonly token: string,
  ) {}
}

Après

import {Component, inject} from '@angular/core';
import {MyService} from './service';
import {DI_TOKEN} from './token';

@Component({template: ''})
export class MyComp {
  private service = inject(MyService);
  readonly token = inject(DI_TOKEN, {optional: true});
}

Options de la migration

La migration propose plusieurs options pour personnaliser son résultat.

path

Détermine quel sous-chemin de votre projet doit être migré. Passez . ou laissez vide pour migrer tout le répertoire.

migrateAbstractClasses

Angular ne vérifie pas que les paramètres des classes abstraites sont injectables. La migration ne peut donc pas les migrer de façon fiable vers inject sans risquer de casser du code : c'est pourquoi elle est désactivée par défaut pour ces classes. Activez cette option si vous voulez que les classes abstraites soient migrées, mais notez que vous devrez peut-être corriger certaines régressions à la main.

backwardsCompatibleConstructors

Par défaut, la migration essaie de nettoyer le code autant que possible, ce qui inclut la suppression des paramètres du constructeur, voire du constructeur entier s'il ne contient aucun code. Dans certains cas, cela peut provoquer des erreurs de compilation quand des classes avec des décorateurs Angular héritent d'autres classes avec des décorateurs Angular. Si vous activez cette option, la migration génère une signature de constructeur supplémentaire pour préserver la rétrocompatibilité, au prix de davantage de code.

Avant

import {Component} from '@angular/core';
import {MyService} from './service';

@Component({template: ''})
export class MyComp {
  constructor(private service: MyService) {}
}

Après

import {Component, inject} from '@angular/core';
import {MyService} from './service';

@Component({template: ''})
export class MyComp {
  private service = inject(MyService);

  /** Inserted by Angular inject() migration for backwards compatibility */
  constructor(...args: unknown[]);

  constructor() {}
}

nonNullableOptional

Si l'injection échoue pour un paramètre avec le décorateur @Optional, Angular renvoie null, ce qui signifie que le type réel de tout paramètre @Optional est | null. Cependant, comme les décorateurs ne peuvent pas influencer leurs types, beaucoup de code existant a un type incorrect. Le type est corrigé dans inject(), ce qui peut faire apparaître de nouvelles erreurs de compilation. Si vous activez cette option, la migration ajoute une assertion non nulle après l'appel à inject() pour correspondre à l'ancien type, au risque de masquer des erreurs de type.

Note : les assertions non nulles ne sont pas ajoutées aux paramètres déjà typés comme nullables, car le code qui en dépend tient probablement déjà compte de leur nullabilité.

Avant

import {Component, Inject, Optional} from '@angular/core';
import {TOKEN_ONE, TOKEN_TWO} from './token';

@Component({template: ''})
export class MyComp {
  constructor(
    @Inject(TOKEN_ONE) @Optional() private tokenOne: number,
    @Inject(TOKEN_TWO) @Optional() private tokenTwo: string | null,
  ) {}
}

Après

import {Component, inject} from '@angular/core';
import {TOKEN_ONE, TOKEN_TWO} from './token';

@Component({template: ''})
export class MyComp {
  // Note the `!` at the end.
  private tokenOne = inject(TOKEN_ONE, {optional: true})!;

  // Does not have `!` at the end, because the type was already nullable.
  private tokenTwo = inject(TOKEN_TWO, {optional: true});
}