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).

Relaterte artikler