vue.js - Tip personalizat Typescript pentru biblioteca JS, importul nu funcționează


Am un proiect Vue cu TypeScript și import un tip personalizat pe care l-am creat pentru vue-numeral-filter, dar asta generează eroarea:

EROARE în /Users/bmartins/Development/app-invest/src/main.ts(14,30): 14:30 Nu s-a putut găsi un fișier de declarație pentru modulul 'vue-numeral-filter'. '/Users/bmartins/Development/app-invest/node_modules/vue-numeral-filter/dist/vue-numeral-filter.es.js' are implicit un tip 'any'. Încercați npm install @types/vue-numeral-filter dacă există sau adăugați un fișier nou de declarație (.d.ts) care să conțină declare module 'vue-numeral-filter';

În fișierul meu main.ts am:

import Vue from 'vue';
import App from './App.vue';
import Vuetify from 'vuetify';
import vuetify from './plugins/vuetify';
import router from './router';
import VueApexCharts from 'vue-apexcharts';
import Vuex from 'vuex';
import store from './store';
import { mockStore } from './test/mock/store';
import * as moment from 'moment';
import 'moment/locale/pt-br';
import VueMoment from 'vue-moment';
import { API_URL, PRODUCT_TYPES } from './store/constants';
import VueNumeralFilter from 'vue-numeral-filter';

Vue.component('apexchart', VueApexCharts);

Vue.use(Vuetify);
Vue.use(Vuex);
Vue.use(VueNumeralFilter, { locale: 'pt-br' });
Vue.use(VueMoment, {
  moment,
});

Pentru tip creez structura folderului:

App 
|_ src 
|_ types    
   |_ vue-numeral-filter
        |_ index.d.ts

Structura folderului

Fișierul index.d.ts pe care l-am creat pe baza @types/vue-moment:

import Numeral from 'numeral';
import { PluginObject } from 'vue';

declare namespace VueNumeralFilterPlugin {
  interface Options {
    // The optional (self-maintained) numeral instance
    numeral?: Numeral;
  }
  interface VueStatic extends Numeral {
    (inp?: Numeral, format?: string): string;
    (inp?: Numeral): string;
  }
}

declare module 'vue-numeral-filter' {
  interface Vue {
    $numeral: VueNumeralFilterPlugin.VueStatic;
  }
}

type VueNumeralFilter = PluginObject<undefined>;

declare const VueNumeralFilter: VueNumeralFilter;
export = VueNumeralFilter;

Și ultima parte a fost schimbarea fișierului tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "typeRoots": [
      "./types"
    ],
    "types": [
      "webpack-env",
      "vue-numeral-filter",
      "vuetify-form-base"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Am citit această postare TypeScript 2: tipuri personalizate pentru modulul npm neintrodus, de mai multe ori, care are o explicație uimitoare, dar tot nu am reușit să înțeleg cum să rezolv problema...

Vreo ajutor?

Răspuns #1

Fișierele de definiție de tip pot fi puțin pretențioase în TypeScript. Este foarte ușor să ajungi să scrii ceva ce TypeScript interpretează ca un modul în loc de un fișier de declarație. Când se întâmplă acest lucru, TypeScript începe să aștepte să imporți tipuri direct din fișier, în loc să recunoască declarația de tip încorporată.

Mi se pare că fișierul tău de definiție a tipurilor este incorect. În special, ai import-uri în afara declarației modulului, ceea ce este unul dintre indicatorii pe care TypeScript îi recunoaște ca semnal că este un modul. Dacă muți import-urile astfel încât să fie în interiorul blocului declare { ... }, cred că va începe să funcționeze.

Pe o altă notă, cred că intrările typeRoots și types din fișierul tău tsconfig.json sunt prea restrictive. Nu cred că asta cauzează problema aici, dar cred că ar trebui să le elimini, altfel vei avea probleme la instalarea tipurilor terță parte în viitor.