JS lib的Typescript自定义类型,导入不起作用
Posted
技术标签:
【中文标题】JS lib的Typescript自定义类型,导入不起作用【英文标题】:Typescript Custom Type for JS lib, import not working 【发布时间】:2021-01-12 06:32:03 【问题描述】:我有一个带有 typescript 的 vue 项目,并且我正在导入我为 vue-numeral-filter 创建的自定义类型,但这会产生错误:
/Users/bmartins/Development/app-invest/src/main.ts(14,30) 中的错误: 14:30 找不到模块“vue-numeral-filter”的声明文件。 '/Users/bmartins/Development/app-invest/node_modules/vue-numeral-filter/dist/vue-numeral-filter.es.js' 隐含了一个 'any' 类型。 尝试
npm install @types/vue-numeral-filter
(如果存在)或添加包含declare module 'vue-numeral-filter';
的新声明(.d.ts)文件
在我的 main.ts 文件中,我有:
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,
);
对于我创建文件夹结构的类型:
App
|_ src
|_ types
|_ vue-numeral-filter
|_ index.d.ts
Folder Structure
我基于@types/vue-moment创建的index.d.ts:
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;
最后一部分是更改 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"
]
我看了这篇TypeScript 2: custom typings for untyped npm module的帖子,看了好几遍,里面的解释很神奇,但还是不知道怎么解决……
有什么帮助吗?
【问题讨论】:
【参考方案1】:Typescript 中的类型定义文件可能有点挑剔。很容易写出 TypeScript 解释为模块而不是声明文件的东西。发生这种情况时,TypeScript 开始期望您直接从文件中导入类型,而不是识别嵌入的类型声明。
在我看来,您的类型定义文件不正确。特别是,您在模块声明之外有 import
s,这是 TypeScript 识别为模块标记的标志之一。如果你移动你的import
s 使它们在declare ...
块内,我认为它会开始工作。
另一方面,我认为tsconfig.json
文件中的typeRoots
和types
条目过于严格。我认为这不是导致问题的原因,但我认为您应该删除它们,否则您将来安装 3rd-party 类型将遇到问题。
【讨论】:
感谢您的回答!我还注意到,如果我采用确切的声明文件并移动到 @types 文件夹中的 node_module 它可以工作!似乎 node_modules 中的声明文件也有一些差异解释!以上是关于JS lib的Typescript自定义类型,导入不起作用的主要内容,如果未能解决你的问题,请参考以下文章