Typescript Custom Type dla JS lib, import nie działa

Sep 26 2020

Mam projekt vue z maszynopisem i importuję niestandardowy typ, który tworzę dla vue-numeral-filter , ale to generuje błąd:

BŁĄD w /Users/bmartins/Development/app-invest/src/main.ts(14,30): 14:30 Nie można znaleźć pliku deklaracji dla modułu „vue-numeral-filter”. „/Users/bmartins/Development/app-invest/node_modules/vue-numeral-filter/dist/vue-numeral-filter.es.js” ma niejawnie typ „any”. Spróbuj, npm install @types/vue-numeral-filterjeśli istnieje, lub dodaj nowy plik deklaracji (.d.ts) zawierającydeclare module 'vue-numeral-filter';

W moim pliku main.ts mam:

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,
});

Dla typu tworzę strukturę folderów:

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

Struktura folderów

Utworzony przeze mnie index.d.ts na podstawie @ 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;

A ostatnią częścią była zmiana 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"
  ]
}

Czytałem ten post TypeScript 2: niestandardowe typy dla nietypowego modułu npm , kilka razy, co ma niesamowite wyjaśnienie, ale nadal nie wiedziałem, jak to naprawić ...

Jakaś pomoc?

Odpowiedzi

cjol Oct 05 2020 at 15:45

Pliki definicji typów mogą być nieco skomplikowane w programie Typescript. Bardzo łatwo jest napisać coś, co TypeScript interpretuje jako moduł zamiast pliku deklaracji. W takim przypadku TypeScript zaczyna oczekiwać, że typy zostaną zaimportowane bezpośrednio z pliku, zamiast rozpoznawać deklarację typu osadzonego.

Wydaje mi się, że plik definicji typu jest nieprawidłowy. W szczególności masz imports poza deklaracją modułu, która jest jedną z flag rozpoznawanych przez TypeScript jako znacznik modułu. Jeśli przesuniesz swoje importlitery tak, aby znalazły się wewnątrz declare { ... }bloku, myślę, że zacznie działać.

Z drugiej strony uważam, że wpisy typeRootsi typesw twoim tsconfig.jsonpliku są zbyt restrykcyjne. Nie sądzę, że to jest przyczyną problemu, ale myślę, że powinieneś je usunąć, w przeciwnym razie będziesz mieć problemy z instalacją typów innych firm w przyszłości.