Vad är skillnaden på de olika sätten att importera bibliotek i TypeScript?


Jag har ganska stora svårigheter med att använda externa bibliotek med TypeScript. Jag skulle väldigt gärna vilja lägga till egna typer för de bibliotek som inte har typer tillgängliga, och jag har svårt att förstå hur imports och requires fungerar med typer.

Vad är skillnaden, och hur ser en motsvarande typning ut för följande situationer:

import something = require('something');
import * as something from 'something';
const something = require('something');
import {something} from 'something';

Svar #1

require är det "gamla" sättet att importera externa moduler och import-syntaxen är det nuvarande rekommenderade sättet som är anpassat till ES6-syntaxen. Beroende på vilket module som är konfigurerat i tsconfig.json kommer TypeScript att transpilerar denna syntax till relevant modultyp/-stil.

Om du vill lära dig hur TypeScript hanterar externa moduler (den stöder två lägen node och classic - kan konfigureras i tsconfig.json som moduleResolution) kan du läsa dokumentationen här: http://www.typescriptlang.org/docs/handbook/module-resolution.html. Den största skillnaden handlar om hur icke-relativa modulvägar löses.

Om du vill lära dig om hur och var TypeScript letar efter typings (typdeklarationer) kan du läsa det här blogginlägget: http://ivanz.com/2016/06/07/how-does-typescript-discover-type-declarations-definitions-javascript/. Från bloggen - det kommer att:

  1. Prova module.d.ts bredvid module.js för anpassad kod
  2. Försök kolla efter en typings: i packages.json för node-moduler (i node_modules)
  3. Försök att leta efter eventuella ambient-deklarationer (declare module X-syntax) i hela bunten av filer som den bearbetar när tsconfig.json finns. Detta är viktigt, eftersom närvaron av den filen får TypeScript att behandla alla inkluderade filer som ett enda "projekt"/"arbetsyta".
  4. Titta efter trippla snedstreck-kommentarer /// <reference path="path/to/declarations.d.ts" /> - jag rekommenderar inte detta längre eftersom en tsconfig.json-projektfil kan användas.

Du har också två typer av skrivningar:

  1. Externa modultypningar - finns bredvid filen eller, i fallet med node-moduler, finns en sökväg till dem i typings: i project.json. Syntaxen är export X utan en modulförklaring (filen är en modul!). Tänk på dem som att de är "bundna" till kodfilen och något i stil med "Så här ser denna modul ut"

  2. Ambienta typer - fungerar var som helst. Syntaxen är declare module X. Tänk i termer av "Det finns en typ/modul X någonstans och så här ser den ut". För moduler kommer TypeScript att matcha baserat på modulens namn. Ett annat användningsområde är globala variabler (t.ex. jQuerys $).

Dokumentationen för vad och hur som kan konfigureras i tsconfig.json kan läsas här: https://github.com/Microsoft/TypeScript/wiki/tsconfig.json

När det gäller de olika exempel som du gav - låt oss säga att du har en modul som heter moduleA. En sak att notera är att en fil är en modul i JS/TS-världen, så:

moduleA.ts

export class Car
{
    public model: string = "";
}

moduleA.js - transpilerad (mål ES5 och modultyp CommonJS)

"use strict";
var Car = (function () {
    function Car() {
        this.model = "";
    }
    return Car;
}());
exports.Car = Car;

main.ts

import moduleA = require("./moduleA");

new moduleA.Car();

// equivalent to the above - import everything under myModuleName
import * as myModuleName from './moduleA';

new myModuleName.Car();

// import only the Car class
import {Car} from './moduleA'

new Car();

// import only the Car class and alias it as MyCar
import {Car as MyCar} from './moduleA'

new MyCar();

main.js - transpilerad (mål ES5 och modultyp CommonJS)

"use strict";
var moduleA = require("./moduleA");
new moduleA.Car();

// equivalent to the above - import everything under myModuleName
var myModuleName = require('./moduleA');
new myModuleName.Car();

// import only the Car class
var moduleA_1 = require('./moduleA');
new moduleA_1.Car();

// import only the Car class and alias it as MyCar
var moduleA_2 = require('./moduleA');
new moduleA_2.Car();