Miten saada VS Code/TypeScript-automaattitäydennys ilman kirjaston tuontia
Jos moduuli (esim. moment.js, knockout tai big.js) sisällytetään <script>-tagilla, esim.
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js">
</script>
jotka määrittelevät globaalin ominaisuuden (esim. moment, ko, Big jne.), kuinka voi käyttää/määritellä tyyppejä window- tai global-objektissa Typescriptissä.
Esimerkiksi
const x = moment()
const t = ko.observable()
const b = new Big()
Kuinka voi asettaa näiden globalien ympäristötyypin ilman, että koko moment.js -kirjastoa otetaan mukaan? Tavoitteena on saada oikein tyypitetyt globaaliviittaukset, joita voivat käyttää VS Code sekä tsc, ts-loader tai babel-typescript.
Tapauksessa moment tyypit ovat esillä kohdassa node_modules/moment/moment.d.ts, mutta muiden kirjastojen (esim. knockout tai big.js) osalta ne ovat kohdassa @types/[module]/index.d.ts.
Tuntuu siltä, että tämä olisi melko yleistä, mutta en ole nähnyt hyvää, toimivaa esimerkkiä siitä, miten tämän voisi toteuttaa.
Tässä on tsconfig:
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"strict": false,
"isolatedModules": false,
"esModuleInterop": true,
"noResolve": false,
"baseUrl": ".",
"paths": {
"*": [
"*",
"js.packages/*"
]
},
"jsx": "preserve",
"outDir": "dist/"
},
"include": [
"js.packages/**/*.ts",
"js.packages/**/*.tsx",
"js.packages/@types/lib.d.ts",
],
"files": [
"services/app/src/entry.js"
],
"exclude": [
"node_modules"
]
}
Tässä on lib.d.ts
declare global {
type Bigable = Big | string | number
interface Window {
Big: typeof import('big.js'),
moment: typeof import('moment'),
Sentry: typeof import('@sentry/browser'),
}
}
ja näin kulutuksen tulisi toimia:
const v = new Big(1)
const m = moment()
const s = global.Sentry()
const o = ko.observable()
joka näyttää tältä VS Codessa (punainen alleviivaus osoittaa virheet):
Joten knockout toimii, koska @types/knockout/index.d.ts sisältää:
declare var ko: KnockoutStatic;
declare module "knockout" {
export = ko;
}
kun taas olen samalla tavalla julistanut globaalin Big Window-rajapinnassa.
Valitettavasti Sentry ja moment (tässä esimerkissä) eivät näytä toimivan, eikä ole selvää, miksi tai mitä pitäisi tehdä tämän korjaamiseksi.
Vastaus #1
Sinulla on oikea ajatus, sinun täytyy käyttää import-tyyppiä saadaksesi tyypit importissa, sinun täytyy ilmoittaa muuttujat global-alueella. Ongelma on, että ilmoitat ominaisuudet Window-objektille. Vaikka mikä tahansa Window-objektille määritetty avain tulee globaaliksi muuttujaksi, TypeScript ei heijasta tätä. Voit ilmoittaa muuttujat suoraan globaalissa alueessa.
declare global {
export var moment: typeof import('moment');
export var Sentry: typeof import('@sentry/browser');
}
const m = moment()
Sentry.init({}) // Sentry() does not seem like it should work according to docs
Vastaus #2
Kysymys ei ole erityisen tarkka yhdelle alustatyypille, mutta kerron sinulle, miten saan moment-kirjaston toimimaan Angularissa.
Ensinnäkin, sinun ei pitäisi ladata skriptin URL-osoitteesta. Sinun tulisi suorittaa npm install moment laittaaksesi sen node_modules-kansioosi. Tämä varmistaa, että se pakataan sovelluksesi minifioituun versioon. Sinun ei tarvitse, mutta tämä on vahvasti suositeltavaa.
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/moment/moment.js",
...
]
Edellä mainitusta huolimatta, kun olet linkittänyt skriptin tsconfig-tiedostoosi (tai angular.json), käyttö on yhtä yksinkertaista kuin seuraava rivi tiedoston alussa:
import * as moment from 'moment';Minulla on tapana käyttää tätä syntaksia useimmissa kirjastoissa, joilla on objekti, esim. shortid, linq ja lodash.
Muut kirjastot toimivat paremmin declare var -lauseiden kanssa. Esimerkiksi olen huomannut, että jQuery toimii paremmin sillä tavalla.
declare var $Automaattinen täydennys
Jos etsit automaattista täydennystä, sinun on ladattava kirjastoille .d.ts-tiedosto. moment-npm-paketti sisältää sellaisen, mutta joillekin kirjastoille on asennettava toinen npm-paketti tätä varten (esim. @types/lodash, @types/jquery).
Visual Studio Autocomplete -toiminto perustuu .d.ts-tiedostoihin tyyppejä tunnistaakseen. Tämän ominaisuuden määritystä koskeva dokumentaatio löytyy täältä, ja sitä voi olla mahdollista määrittää (katso huomautus lähes alareunasta).
