angular - Hvordan bruke typer med dynamiske importer?


Jeg bruker dynamiske imports med Angular 7 for å redusere størrelsen på den opprinnelige leverandørpakken.

import('xlsx').then(XLSX => {
    const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
})

Men det er en feil på XLSX.WorkBook-typen som sier:

Cannot find namespace XLSX.

XLSX.read fungerer fint.

Spørsmål: Hvordan definerer jeg typer når jeg bruker dynamiske imports?

Svar #1

XLSX vil bare representere verdien av importen, ikke typene.

Du har to alternativer.

Bruk en importtype:

import('xlsx').then(XLSX => {
    const wb: import('xlsx').WorkBook = XLSX.read(bstr, { type: 'binary' });
})

Du kan definere et typealias for å gjøre dette enklere: type WorkBook=import('xlsx').WorkBook

Importer typen:

import { WorkBook } from 'xlsx' // Just for the type, will be elided in this example

import('xlsx').then(XLSX => {
    const wb: WorkBook = XLSX.read(bstr, { type: 'binary' });
})

Dette andre alternativet er mer vanskelig å få riktig, hvis du kun bruker importene fra den statiske importen i typer, bør importsetningen utelates (dvs. ikke bli skrevet ut til JS). Så snart du bruker noen import fra den statiske importen i et uttrykk (dvs. hvilken som helst posisjon som vil ende opp i JS), vil importen ikke bli utelatt. Se mer om modul som blir utelatt

Svar #2

Jeg kjenner ikke konteksten din, så jeg antar to ting:

  1. Du definerte en XLSX-type andre steder, men XLSX-parameteren overskygger den eksterne variabelen. For å unngå overskygging, bare bruk et annet navn for parameteren (for eksempel ved å legge til en understrek):

    import('xlsx').then(_XLSX => {
        const wb: XLSX.WorkBook = _XLSX.read(bstr, { type: 'binary' });
    })
    
  2. Du tror at XLSX.WorkBook er en type, men det er det ikke! XLSX er et JavaScript-bibliotek, og JavaScript har ikke et konsept av type. Når du også bruker TypeScript, blir det transpillert til JavaScript og all informasjon om type går tapt. Det finnes ingen løsning på dette problemet, men sannsynligvis må du importere typen fra et annet sted, for eksempel DefinitelyTyped. Bare importer typen i komponenten din, så vil du kunne bruke den.

Relaterte artikler