2 votes

Comment éviter la double vérification du non-nullable dans les unions discriminées de TypeScript ?

Dans le code ci-dessous TypeScript ne croit pas que si customMessage es undefined , className n'est PAS undefined :

export default class ClassRequiredInitializationHasNotBeenExecutedError extends Error {

  public static readonly NAME: string = "ClassRequiredInitializationHasNotBeenExecutedError";

  public constructor(
      parametersObject: {
        customMessage: string;
        className?: undefined;
      } | {
        className: string;
        customMessage?: undefined;
      }
  ) {

    super();

    this.name = ClassRequiredInitializationHasNotBeenExecutedError.NAME;

    if (typeof parametersObject.customMessage !== "undefined") {
      this.message = parametersObject.customMessage;
    } else {
      this.message = ClassRequiredInitializationHasNotBeenExecutedError.buildMessage({
          className: parametersObject.className
      })
    }
  }

  private static buildMessage(parametersObject: { className: string }): string {
    return `The class '${parametersObject.className}' has not been executed;`
  }
}

Violon

Erreur :

Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.(2322)

Je sais que si je fais une double vérification, c'est comme ça :

if (typeof parametersObject.customMessage !== "undefined") {
    this.message = parametersObject.customMessage;
} else if (typeof parametersObject.className !== "undefined") {
    this.message = ClassRequiredInitializationHasNotBeenExecutedError.buildMessage({
        className: parametersObject.className
})

L'exemple ci-dessus fonctionnera, mais :

  1. Je veux éviter else if (typeof parametersObject.className !== "undefined") si possible
  2. Event l'a laissé, TypeScript ne croira pas que l'un des éléments suivants customMessage o className a été initialisé. Voici l'exemple quand c'est critique :

    let message: string;

    if (typeof parametersObject.customMessage !== "undefined") { message = parametersObject.customMessage; } else if (typeof parametersObject.className !== "undefined") { message = ClassRequiredInitializationHasNotBeenExecutedError.buildMessage({ className: parametersObject.className }) }

    console.log(message.length)

    Variable 'message' is used before being assigned.(2454)

Veuillez noter que cette question porte sur la manière de faire croire à TypeScript que si customMessage es undefined , className n'est PAS indéfinie et vice versa, et non pas comment initialiser this.message (le ClassRequiredInitializationHasNotBeenExecutedError est juste un exemple)

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