visual studio - TypeScript VS - pogreške pri kompajliranju, ali bez pogrešaka u dizajnerskom vremenu


U Visual Studio 2017 pokušavam koristiti ES2015 Promiseove. Koristim TypeScript 2.1.5. Imam tsconfig.json datoteku u rješenju i izgleda ovako:

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "outFile": "outfile.js",
    "lib": [ "dom",  "es2015.promise", "es5" ]
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

Kompajliram i dobivam pogreške u tipiziranju, na primjer:

error TS2339: Build:Svojstvo 'then' ne postoji za tip 'Promise'.

Kada idem na pogrešku, imam intellisense koji pokazuje da zapravo prepoznaje funkciju then, i mogu desnim klikom ići na definiciju, što me vodi do lib.es2015.promise.d.ts.

Zašto dizajnersko vrijeme radi, a vrijeme kompajliranja ne, i kako to popraviti?

Odgovor #1

Svojstvo tsconfig.json naziva libs - poveznica na strašnu službenu tsconfig dokumentaciju ovdje - samo pruža tipove tako da, na primjer, vaše razvojno okruženje može otići do definicije tipa, zaključiti tipove i automatski dovršiti kod. Ne ubacuje implementaciju tih klasa u vaš ugrađeni JS kod; u mnogim slučajevima ciljno okruženje (npr. preglednik) pruža vlastitu implementaciju Promise, tako da to nije potrebno. Ubacivanje implementacije je odgovornost koja ostaje na programeru :(

Evo kako pružiti Promise koji se čak može prevesti za ES3...

Korak 1: Instalirajte shim koji pruža Promise

U korijenu vašeg projekta pokrenite ovu naredbu (pod pretpostavkom da tamo imate package.json):

npm install --save es6-promise

Korak 2: Učinite ga dostupnim svom kodu

Dodajte ovaj redak u bilo koju .ts datoteku koja koristi Promise:

import {Promise} from 'es6-promise';

Korak 3: Učinite vaš tsc kompajler svjesnim tipova

Uređivat ću vašu trenutnu tsconfig.json datoteku ovdje:

{
  "compilerOptions": {
    // I've moved "noImplicitAny" to below.
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es3", // We can target ES3 with this method, if we want!
    "outFile": "outfile.js",

    /* From http://stackoverflow.com/a/32410515/5951226 : part of this block adds support for ES6 Promises */
    "noImplicitAny": false,
    "declaration": false,
    "module": "commonjs",
    "noLib": false
  },
  "exclude": [
    // "node_modules", // We'll need to include "node_modules/es6-promise", so I'll leave it to you to play around with your inclusions/exclusions which are unique to your own use case.
    "wwwroot"
  ]
}

Ako stvarno trebate isključiti node_modules (što mislim da je neuobičajen slučaj - sigurno se možete to zaobići..?), možete premjestiti es6-promise biblioteku na zasebnu lokaciju i uvoziti je specifično s te lokacije umjesto da koristite automatsko rješavanje modula.