ProgrammatieFrontend ontwikkelaar

Hoe werkt het typemechanisme voor geïmporteerde JavaScript-modules in TypeScript? Hoe typiseer je een import als het oorspronkelijke JS-bestand geen types bevat? Wat zijn de nuances en risico's van het gebruik van any bij import?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Achtergrond van de vraag:

TypeScript is bedoeld om statische typering toe te voegen aan bestaande JS-toepassingen. De vraag rijst — hoe typiseer je een import als we een externe of eigen module importeren die in puur JavaScript is geschreven, waar geen types zijn? In dit geval gebruikt TypeScript zogenaamde declaration files (.d.ts), of het zal types automatisch afleiden (soms verkeerd).

Probleem:

Als TypeScript bij het importeren geen geschikte typebeschrijving kan vinden, krijgt de variabele het type any, wat betekent — volledige verlies van type-veiligheid. Dit kan leiden tot fouten die de compiler niet detecteert, en tot bugs tijdens runtime. Vaak vergeten ontwikkelaars expliciet types voor geïmporteerde functies/objecten te declareren.

Oplossing:

  1. Voor eigen JS-modules kun je handmatig type-declaraties schrijven ( .d.ts bestanden).
  2. Voor populaire bibliotheken zijn er vaak @types/pakketten beschikbaar.
  3. Je kunt expliciet types bij de import declareren en zelf de structuur van het benodigde object beschrijven.
  4. Het wordt aanbevolen om any te vermijden en, als dat niet mogelijk is, het gebruik ervan minimaal te beperken.

Voorbeeldcode:

// 1. Expliciete typisering van een JS-module-import import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Importeren van een JS-module voor welke een myLib.d.ts bestand is gemaakt met export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Geïmporteerde module zonder typisering en expliciet type beschrijven import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;

Belangrijke kenmerken:

  • Bij afwezigheid van declaraties krijgt de geïmporteerde waarde standaard het type any, wat type-veiligheid ondermijnt.
  • De beste aanpak is om .d.ts bestanden te maken voor externe modules/eigen bibliotheken.
  • Waar nodig kunnen externe functies/modules lokaal worden gedeclareerd via declare/interfaces.

Lastige vragen.

Kan TypeScript automatisch de types van een geïmporteerde JS-module afleiden zonder declaraties?

Nee, als het bestand in JavaScript is geschreven en er geen type-declaraties zijn, is TypeScript gedwongen om any te veronderstellen en verliest het type-informatie behalve voor triviale gevallen (export const x = 1;).

Is het mogelijk om geïmporteerde types 'uit te breiden' als er nieuwe velden in de JS-module verschijnen?

Slechts als je het declaratiebestand (.d.ts) bijwerkt. Als de types zijn vastgelegd in .d.ts, zal TypeScript deze als 'waarheid' gebruiken en blijven nieuwe velden ofwel ongetypeerd of leiden tot een fout.

Is het veilig om een externe JS-module in een TypeScript-project te importeren als er geen @types/ en declaraties zijn?

Nee, dit vermindert de veiligheid aanzienlijk - al het werk met de import wordt untyped (any), de compiler zal geen fouten genereren, zelfs niet als de module niet beschikbaar is of de API is gewijzigd. Werken met zulke modules is alleen toegestaan als een tijdelijke oplossing, met expliciete typisering of isolatie van de code.

Typefouten en anti-patronen

  • Vergeten van declaraties (.d.ts) voor externe pakketten.
  • Blinde vertrouwen in implicit any bij het importeren van JS-modules.
  • Overschrijding van de grenzen van type-veilige code.

Voorbeeld uit de praktijk

Negatieve case

Een ontwikkelaar importeert een externe JS-bibliotheek zonder declaraties, gebruikt vol vertrouwen de API en krijgt type any. Na de update van de bibliotheek verandert de handtekening van de methoden, maar er ontstaan geen fouten, enkel bugs tijdens runtime.

Voordelen:

  • Snel en eenvoudig een willekeurige JS-module aansluiten.

Nadelen:

  • Geen garanties voor type-veiligheid, fouten blijven onopgemerkt tot uitvoering.

Positieve case

Er wordt een declaratiebestand .d.ts gemaakt of een @types/pakket toegevoegd, de beschrijving van de API stemt strikt overeen met de oorspronkelijke JS-module. Alle geïmporteerde methoden zijn getypeerd, de IDE biedt autocompletion aan, eventuele discrepanties tonen een compileerfout aan.

Voordelen:

  • Type-veiligheid, waarschuwingen over fouten vóór uitvoering.
  • Ondersteuning voor autocompletion en documentatie direct in de code.

Nadelen:

  • Vereist tijd voor het schrijven van .d.ts, onderhoud van types bij updates van de JS-module.