4 votes

Valider une entrée avec un type personnalisé Angular

J'ai un composant avec une entrée définie comme un type personnalisé.

@Input() public labelSize: 'small' | 'normal' | 'large'  = 'normal';

Mais apparemment, je peux passer n'importe quel type de paramètre à la balise component. Je n'aurai jamais d'erreur ou d'avertissement.

<my-component labelSize="whatever"></my-component>

Je peux passer un numéro par événement

<my-component labelSize=12345></my-component>

Je m'attendais à ce que le compilateur typescript ou angular me donne un retour sur ce genre d'erreur.

Je suis censé valider moi-même le type de toutes les entrées de mes composants ?

Quelles sont les meilleures pratiques ?

Remerciements

1voto

Ovidiu Dolha Points 3496

Les templates angular sont HTML et ne sont en aucun cas accrochés à des typescript pour vérifier cela. Et même dans typescript, il est permis de contourner la déclaration de type, par ex. this.labelSize = 'whatever' as any .

Au final, le code reste du javascript. Et dans les modèles, c'est comme si on utilisait du javascript simple depuis le début.

Si l'on veut vraiment attraper les décalages à l'avant, voici quelques solutions possibles :

1. La validation

Comme cela a déjà été suggéré, procédez à une validation manuelle ou utilisez une bibliothèque de validation pour spécifier les contraintes, par exemple https://validatejs.org/

D'ailleurs, vous pouvez aussi utiliser un Pipe pour ajouter une validation à la volée sur n'importe laquelle de vos valeurs et avoir plus de clarté sur votre html.

2. Objets de configuration

Vous pouvez capturer la configuration des composants lorsque les types sont importants dans un objet, comme suit

@Input() public config: {
  labelSize: 'small' | 'normal' | 'large';
} = { labelSize: 'normal' }

puis lier l'entrée à myCompConfig :

<my-component [config]="myCompConfig"></my-component>

puis dans votre contrôleur où vous l'utilisez

this.myCompConfig = { labelSize: 'whatever' } // error <- type is enforced now

3. TS pour les modèles

Vous pouvez utiliser TS au lieu de HTML pour les modèles, et l'assister avec quelques informations de type :

Partagez d'abord votre type

export type LabelSize = 'small' | 'normal' | 'large'

@Input() public labelSize: LabelSize = 'normal';

mon-modèle.ts

const labelSize: LabelSize = 'whatever' // error <- type is enforced 

export const template = `
    <my-component labelSize=${labelSize}></my-component>`
`;

puis l'utiliser directement dans votre composant

import { template } from './my-template.ts';
@Component({ selector: 'something', template })

Vous pouvez par exemple avoir une usine pour créer cet élément sur la base d'un paramètre labelSize (et ce paramètre peut contenir des informations sur le type).

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