Bij herhaalde soortgelijke typedeclaraties zoekt men in TypeScript naar berekening van een resultaattype uit een invoertype. Belangrijker dan minder tekens is of lezers de relatie begrijpen. Een fictieve verzendmeldingsdienst illustreert conditionele typen en infer, apart van controle of externe gegevens werkelijk juist zijn.
1. Conditionele typen vertakken met een type als invoer
De officiële documentatie legt resultaatafweging via extends uit. Het voorbeeld maakt een booleaans literaltype afhankelijk van een stringtype. Het is geen functie die tijdens uitvoering strings test.
type IsText<T> = T extends string ? true : false;
type NameIsText = IsText<'parcel'>; // true
type CountIsText = IsText<3>; // false
Stel dat meldingen een string-ID ontvangen en interne verwerking een numerieke. Voor conditionele typen moet u uitleggen waarom ze verschillen. Verschillende betekenissen verdienen eigen namen; enkel notatieverschil kan duidelijker worden door één invoervorm. Verberg onduidelijk gegevensontwerp niet achter typetechniek.
Noteer verwachte invoer en resultaat als paren. Kleine voorbeelden van strings, getallen, unions en onverwachte invoer verlichten complexe declaraties. Vergelijk commentaar met het door de editor afgeleide type. Een natuurlijk klinkende naam garandeert geen overeenkomend berekend resultaat.
2. Uniondistributie verandert de betekenis van arrays
Wanneer de typeparameter rechtstreeks links van de voorwaarde staat, wordt die over elk unionlid verdeeld. Om de hele union als eenheid te behandelen vergelijkt u de versie met vierkante haken.
type SeparateLists<T> = T extends unknown ? T[] : never;
type Together<T> = [T] extends [unknown] ? T[] : never;
type A = SeparateLists<string | number>; // string[] | number[]
type B = Together<string | number>; // (string | number)[]
const a: A = ['a', 'b'];
const b: B = ['a', 1];
Het eerste is een array met alleen strings of alleen getallen. Het tweede laat ze samen in één array toe. Of de hele verzendlijst één codesoort of elk element andere soorten mag bevatten bepaalt de keuze. Beide tonen haken, niet hetzelfde contract.
Bij problemen voert u leden afzonderlijk in in plaats van meteen de hele complexe utility te lezen. Vergelijk string, getal en hun union. Zodra de bedoelde distributie duidelijk is, kunt u extra haken uitleggen. Bewaar naast eindresultaten voorbeelden van toegestane waarden.
3. infer benoemt een type binnen een structuur
infer geeft een deel van de getoetste structuur in een conditioneel type een naam. Het voorbeeld verwijdert één Promise-laag.
type OneResult<T> = T extends Promise<infer Value> ? Value : T;
type Parcel = OneResult<Promise<{ tracking: string }>>;
type ParcelList = OneResult<Promise<string[]>>;
Deze code voert geen asynchroon werk uit en wacht niet. Ze drukt alleen de resultaatvorm bij compilatie uit. Een naam als Resolved kan een al ontvangen waarde suggereren; kijk naar de gebruikscontext. Wachten tijdens uitvoering blijft asynchrone code.
Voor een recursief afgewacht resultaattype bekijkt u de standaardutility Awaited vóór uitbreiding van het eenlagige voorbeeld. Onderwijseenvoud en eisen aan gedeelde hulpmiddelen verschillen. Documenteer voor teamutility’s invoer met ander resultaat dan standaard en de reden voor dat verschil.
4. Gebeurtenisnamen verbinden met template literals
Template-literaltypen representeren combinaties van stringliterals. De dienst kan domein en actie tot gebeurtenisnaam combineren.
type Scope = 'parcel' | 'address';
type Action = 'created' | 'updated';
type EventName = `${Scope}:${Action}`;
const event: EventName = 'parcel:created';
De compiler vindt typefouten in namen, maar werkelijke geldigheid van alle combinaties is apart. Als alleen adresverwijdering wordt ondersteund, drukt een product van domein en actie de regel misschien niet juist uit. Overweeg eerst expliciete koppeling van toegestane gebeurtenissen en payloads.
Meer gebeurtenissen vragen vindbare werkelijke namen. In plaats van meerlagige automatische combinatieregels kunt u namen voor externe systemen in één bestand zichtbaar houden. Vergelijk hoe nieuwe collega’s voor en na abstractie verkeerde gebeurtenissen vinden. Typeverfijning en bruikbaarheid beoordeelt u samen.
5. Externe JSON moet tijdens uitvoering worden getest
User of Parcel aan een API-respons toekennen garandeert de echte structuur niet. Bekijk ontvangst als unknown gevolgd door eenvoudige veldcontrole.
function hasTracking(value: unknown): value is { tracking: string } {
return typeof value === 'object' && value !== null
&& 'tracking' in value && typeof value.tracking === 'string';
}
const incoming: unknown = { tracking: 'DEMO-001' };
if (hasTracking(incoming)) console.log(incoming.tracking);
De controle bevestigt alleen dat tracking een string is, niet dat het zendingsnummer bestaat of de gebruiker toestemming heeft. Typevernauwing, bedrijfsregels en toegangscontrole zijn verschillende taken. De officiële Narrowing-documentatie toont vernauwing met voorwaarden.
6. Een kleine controlevolgorde voor typehulpmiddelen
Schrijf eerst twee echte toegestane en twee af te wijzen waarden. Druk de betekenis uit met gewone unions en expliciete objecten. Blijven herhaalde relaties, dan verklaren conditionele typen of infer hun nut. Duurt lezen veel langer, extraheer alleen gedeelde delen en laat overige typen gewoon.
Voer type- en runtimecontroles apart uit. Compilerafwijzing van verkeerde namen en begrijpelijke fouten bij ontbrekende servervelden vullen elkaar aan. Kleine voorbeelden controleren en dan met echte invoergrenzen verbinden maakt typeomzetting nuttig voor veilig applicatieontwerp.