Sirkulære avhengigheter i Typescript


Jeg har problemer med å deklarere sirkulære avhengigheter i Typescript. Her er koden:

//Widget.module.ts

    /// <reference path="Buttons.ts" />

export module Widget {

    class Widget {

    }
}

//Buttons.ts

/// <reference path="Widget.module.ts" />

class Button extends Widget{
   function x(){
     ...
   }

   ...

}

I dette oppsettet vil jeg ha en hovedfil som definerer en modul, og deretter et antall filer som refereres til fra den hovedfilen. Disse filene kan inneholde et antall klasser som kaller, instansierer eller arver fra hverandre.

For øyeblikket får jeg denne feilen på linjen som inneholder "extends Widget" i kilden Buttons.ts - enten om det er inne i en eksportert modul eller ikke.

Could not file symbol widget

--Oppdatering--

Grunnen til at jeg vil bruke referansetagger i stedet for import/require er at jeg vil kompilere disse separate Typescript-filene til en enkelt javascript-fil ved å bruke --out-flagget i typescript-kompilatoren.

Svar #1

Jeg antar at de to filene dine er i samme mappe?

Fra den nåværende koden kan jeg ikke forstå hvorfor du skulle ønske å referere til Button.ts i Widget.module.ts-filen, men det er ikke poenget.

Du inkluderer ikke Widget.module-filen, du refererer bare til den. Referering til TypeScript-filer kan kun brukes for typeerklæringer, ikke implementasjoner.

Endre koden din til:

import Widget = require("Widget.module");

class Button extends Widget.Widget {
   x() {
     // ...
   }

   // ...
}

Merk at du må referere til klassen som Widget.Widget da du eksporterer modulen, ikke klassen. Også, hvis du bygger en nettapplikasjon, trenger du en modul-laster for å laste inn widget-modulen. I så fall, ta en titt på RequireJS.

Oppdatering: Fordelen med referansetaggene er at du kan referere til typer uten å måtte importere dem. Dette kan være nyttig

  1. i tilfelle du vil bruke et eksisterende JavaScript-bibliotek i TypeScript-koden din
  2. eller for din egen kode.

I det siste tilfellet, anta for eksempel at du har annen kode som forventer at en variabel skal være av typen Button, men at du faktisk ikke trenger selve klassen.

class MyClassThatReferencesButtonButDoesNotActuallyNeedsTheImplementation {
    myMethodThatExpectsAButton(someVar:Button) {
        someVar.text = "My button!";
    }
}

Klassen trenger ikke implementeringen av Button, den trenger bare å vite hvilke egenskaper og metoder som er tilgjengelige på den. Fordelen blir tydeligere når du forstår at hvis Button ble importert i stedet for referert, må den lastes av en JavaScript-modullaster.

I det første tilfellet, la oss si at din Button-klasse krever jQuery. Kommer du til å inkludere jQuery sammen med klassen din? Eller kommer du til å anta at dette er tilgjengelig globalt? I bunn og grunn er dette det samme tilfellet som det ovenfor: du trenger ikke en TypeScript-implementering av jQuery, du trenger bare å vite hvilke egenskaper og metoder som er tilgjengelige, og derfor vil du bare referere til en definisjonsfil for jQuery.

Flagget --out er kun nyttig for å inkludere refererte filer. Hvis du har importerte moduler, må du kompilere alle filer og deretter bruke RequireJS-optimalisatoren for å bygge utdataene dine til en enkelt fil.

Relaterte artikler