Como obter o autocompletar do VS Code/TypeScript sem importar a biblioteca
Se um módulo (por exemplo, moment.js, knockout ou big.js) for incluído com uma tag <script> por exemplo
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js">
</script>
que definem uma propriedade global (por exemplo, moment, ko, Big, etc), como alguém pode acessar/declarar os tipos em window (ou global) no Typescript.
Por exemplo
const x = moment()
const t = ko.observable()
const b = new Big()
Como alguém pode definir o tipo ambiente desses globais sem incluir toda a biblioteca moment.js? O objetivo é ter referências globais devidamente tipadas para serem usadas pelo VS Code, e tsc, ts-loader ou babel-typescript.
No caso do moment, os tipos são expostos em node_modules/moment/moment.d.ts, mas para outras bibliotecas (por exemplo, knockout ou big.js) eles estão em @types/[module]/index.d.ts.
Parece que isso seria bastante comum, mas eu não vi uma boa referência funcional de como realizar isso.
Aqui está o 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"
]
}
Aqui está um 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'),
}
}
e aqui está como o consumo deve funcionar:
const v = new Big(1)
const m = moment()
const s = global.Sentry()
const o = ko.observable()
que se parece com isto no VS Code (com o sublinhado vermelho indicando falhas):
Então o knockout funciona porque @types/knockout/index.d.ts tem:
declare var ko: KnockoutStatic;
declare module "knockout" {
export = ko;
}
enquanto eu declarei de forma semelhante um Big global em interface Window.
Infelizmente, Sentry e moment (neste exemplo) não parecem funcionar, e não está claro por que ou o que alguém teria que fazer para corrigir isso.
Resposta #1
Você tem a ideia certa, você precisa usar um tipo import para obter os tipos em uma importação, você precisa declarar variáveis no global. O problema é que você está declarando as propriedades em Window. Embora qualquer chave atribuída ao Window se torne uma variável global, o TypeScript não reflete isso. Você pode declarar as variáveis diretamente no escopo global.
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
Resposta #2
A questão não é terrivelmente específica para um tipo de plataforma, mas eu vou te contar como eu faço o moment funcionar no Angular.
Primeiro, você não deveria estar carregando a partir de uma URL de script. Você deveria executar npm install moment para colocá-lo na sua pasta node_modules. Isso garantirá que ele seja incluído na versão minificada da sua aplicação. Você não precisa, mas isso é fortemente recomendado.
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/moment/moment.js",
...
]
Independentemente do exposto acima, uma vez que você tenha o script vinculado em seu tsconfig (ou angular.json), o uso é tão simples quanto a seguinte linha no topo do arquivo:
import * as moment from 'moment';Eu costumo usar essa sintaxe para a maioria das bibliotecas que têm um objeto, por exemplo, shortid, linq e lodash.
Outras bibliotecas funcionam melhor com declarações declare var. Por exemplo, eu descobri que o jQuery funciona melhor dessa maneira.
declare var $Preenchimento automático
Se você está procurando por autocompletar, você precisa ter um arquivo .d.ts carregado para a biblioteca. O pacote npm para moment já vem com um, mas algumas bibliotecas precisam que outro pacote npm seja instalado para isso (por exemplo, @types/lodash, @types/jquery).
O Autocompletar do Visual Studio depende de arquivos .d.ts para identificar tipos. A documentação para configurar esse recurso está localizada aqui, e pode ser possível configurá-lo (veja a nota próxima ao final).
