src/lib/utils.ts — assertNever ir indeksai
Kodo stulpelyje — src/lib/utils.ts su assertNever, toDateParam ir generiniu debounce.
noUncheckedIndexedAccess praktikoje — toDateParam:
const iso = date.toISOString().split('T')[0]; // string | undefined
if (iso === undefined) throw new Error('Could not format date');
return iso; // dabar tik string
split('T')[0] beveik visada egzistuoja — bet tipas to negarantuoja, tad kompiliatorius verčia apdoroti undefined. Vieną eilutę daugiau, bet užuot tikėjęsis, dabar žinai.
assertNever — išsamumas. Įsivaizduok switch per LoadStatus:
function label(status: LoadStatus): string {
switch (status.state) {
case 'idle': return '';
case 'loading': return 'Loading…';
case 'loaded': return 'Done';
case 'error': return status.message;
default: return assertNever(status); // ← visi variantai apdoroti
}
}
Kol visi keturi variantai apdoroti, default šakoje status yra never, ir assertNever(status) kompiliuojasi. Pridedi penktą variantą (pvz. { state: 'stale' }) — status default šakoje nebe never, ir assertNever nustoja kompiliuotis, rodydama tiksliai šitą switch.
Patikrink.
1. Pridėk 'refreshing' variantą į LoadStatus. `npm run typecheck` iškart nurodo
KIEKVIENĄ switch'ą, kuris jo neapdoroja.
2. arr[0] be patikros — klaida „possibly undefined".
Tai — griežtumo dovana augančiai programai: pakeiti tipą, o kompiliatorius tampa tavo „darbų sąrašu" — parodo visas vietas, kurias reikia atnaujinti. Be to tektų medžioti ranka ir tikėtis, kad nieko nepraleidai.
Patarimas (generikai).
debounce<Args extends unknown[]>išsaugo perduodamos funkcijos argumentų tipus. Ne generinis(fn: Function)juos „numestų", ir kviesdamas netektum tikrinimo. Generikai leidžia pernaudojamą kodą neprarandant tipų — tai, ką 7 pamokos vanilladebouncedarė be jokių garantijų.