typescript - Valider input med egendefinert type Angular
Jeg har en komponent med en Input definert som en egendefinert type.
@Input() public labelSize: 'small' | 'normal' | 'large' = 'normal';
Men tydeligvis kan jeg sende hvilken som helst type parameter til komponenttaggen. Jeg vil aldri få noen form for feil/advarsel.
<my-component labelSize="whatever"></my-component>
Jeg kan til og med passere et tall
<my-component labelSize=12345></my-component>
Jeg forventet at TypeScript-kompilatoren eller Angular skulle gi meg noen tilbakemeldinger på denne typen feil.
Skal jeg validere typen til alle inngangene til komponentene mine selv?
Noen beste praksiser?
Takk
Svar #1
De angulære malene er HTML og er på ingen måte koblet til TypeScript for å sjekke dette. Og selv i TypeScript er det tillatt å omgå typedeklarasjonen, for eksempel this.labelSize='whatever' as any.
Til slutt er koden fortsatt javascript. Og i malene er det akkurat som å bruke vanlig javascript fra starten av.
Hvis du virkelig vil oppdage uoverensstemmelser på forhånd, er noen mulige løsninger:
1. Validering
Som allerede foreslått, gjør en manuell validering eller bruk et valideringsbibliotek for å spesifisere begrensninger, f.eks. https://validatejs.org/
Forresten, du kan også bruke en Pipe for å legge til validering på farten på hvilken som helst av dine verdier og få mer klarhet i html-en din.
2. Konfigurasjonsobjekter
Du kan fange konfigurasjonen av komponenter der typer er viktige i et objekt, slik
@Input() public config: {
labelSize: 'small' | 'normal' | 'large';
} = { labelSize: 'normal' }
og bind deretter inngangen til myCompConfig:
<my-component [config]="myCompConfig"></my-component>
deretter i kontrolleren din der du bruker den
this.myCompConfig = { labelSize: 'whatever' } // error <- type is enforced now
3. TS for maler
Du kan bruke TS i stedet for HTML for maler, og hjelpe det med litt typeinformasjon:
Del typen din først
export type LabelSize = 'small' | 'normal' | 'large'
@Input() public labelSize: LabelSize = 'normal';
min-mal.ts
const labelSize: LabelSize = 'whatever' // error <- type is enforced
export const template = `
<my-component labelSize=${labelSize}></my-component>`
`;
bruk det deretter direkte i komponenten din
import { template } from './my-template.ts';
@Component({ selector: 'something', template })
Merk at dette også kan ekstraheres til en fabrikk-tilnærming for å lage deler av templene dine, f.eks. kan du ha en fabrikk for å lage dette elementet basert på en labelSize-param (og denne paramen kan ha typeinformasjon).
