web-dev-qa-db-fra.com

Vérification de type dans Angular 2 modèles

Nous construisons une application en Angular 2 et TypeScript. Nous essayons de vérifier statiquement les types là où c'est possible. Existe-t-il un moyen de vérifier les types dans les modèles? Considérez le fragment suivant:

<foo [data]="dataObj"></foo>

Supposons que data dans le composant Foo ait un type TData. Cependant, par défaut, rien ne m'empêche de passer dataObj qui n'est pas conforme à TData. Existe-t-il une extension TypeScript pour les modèles Angular qui vérifieraient les types dans un tel cas?

43
jfu

Malheureusement, il semble que la version actuelle Angular ne vérifie pas les types d'entrées et d'événements des composants. Vous pouvez utiliser la compilation AOT et activer fullTemplateTypeCheck angular, qui effectue une vérification du type de modèle.

Activez l'option fullTemplateTypeCheck dans src/tsconfig.app.json

{
    "compilerOptions": { ... },
    "angularCompilerOptions": {
        "fullTemplateTypeCheck": true
        ...
    }
}

Et construisez (ou servez) votre projet avec --aot option

ng build --aot

Qu'en est-il de la vérification du type des entrées et des événements, j'ai trouvé deux problèmes sur angular bug tracker ( issue1 and issue2 ). La solution du problème dépend de l'implémentation du moteur de rendu, et il est plus probable que le problème soit résolu dans la prochaine version de angular, appelé Ivy . voici demande de fonctionnalité pour la vérification du type d'entrées dans le rendu ivy.

9
Valeriy Katkov

Je pense qu'un IDE ou linter pourrait attraper cela pour vous, mais si quelqu'un en a vraiment besoin, une option serait de créer un Pipe pour faire la vérification de type au moment de l'exécution.

@Pipe({ name: 'typeCheck' })
export class TypeCheckPipe implements PipeTransform {

  transform(value: any, classType: object): any[] {
    if (value &&
      !(value instanceof classType)
    ) {
        throw new TypeError("Input is not instanceof " + classType + 
                            " but was " + typeof(value));
    }
    return value;
  }
}

Vous pouvez l'utiliser dans un modèle de composant comme celui-ci:

<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>

Le seul problème que j'ai trouvé est que je ne sais pas comment injecter la fonction de classe dans le modèle autrement qu'en tant qu'instance du composant.

@Component({
  selector: 'my-app',
  template: `
  <div>
    <custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>
  </div>
  `,
})
export class App {
  coolInput: CoolInput;
  coolInputClass: object = CoolInput;

  constructor() {
    this.coolInput = "This is the wrong type";
  }
}

Voici un Plunker illustrant le message d'erreur de travail (lancé via Zone). https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview

1
kevinrstone

WebStorm de Jetbrains peut le faire.

Ma réponse originale:

Je ne pense pas qu'il existe un moyen fiable de le faire sans penser comme React le fait avec l'extension JSX ou TSX du langage.

Le compilateur TypeScript ne connaît pas vos fichiers HTML et les ignorera. De plus, il n'y a pas de couplage solide entre vos modèles et le code du contrôleur ... rien ne vous empêche de réutiliser le même modèle sur plusieurs contrôleurs.

0
Victor Högemann