Vue3+TypeScript组件npm包未导出类型检查,编辑器无必填属性提示
我用Vite+TypeScript开发了一个简单的Vue3组件并发布为npm包。组件通过defineProps定义了必填的example字符串属性,本地在App.vue引用时,未传入该属性会触发编辑器错误提示,功能正常。但发布为npm包后,在其他项目中引用时,VSCode不再提示该属性为必填项,仅浏览器控制台会输出对应警告信息。
相关配置文件如下:
组件代码(DemoComponent.vue)
<script setup lang="ts"> const props = defineProps({ example: { type: String, required: true, }, }) </script> <template> <p>{{ example }}</p> </template>
tsconfig.json配置
{ //... "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "moduleResolution": "NodeNext", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "isolatedModules": true, "esModuleInterop": true, "lib": ["ESNext", "DOM"], "skipLibCheck": true, "outDir": "dist", "declaration": true, "paths": { "@/*": ["./src/*"] } }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "exclude": ["**/*.cy.ts", "src/main.ts"] }
vite.config.js配置
import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import dts from 'vite-plugin-dts' import { resolve } from 'node:path' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue(), dts()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), 'vue': 'vue/dist/vue.esm-bundler.js', } }, build: { lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'ExamplePackage', fileName: 'example-package', }, rollupOptions: { external: ['vue'], output: { globals: { vue: 'Vue', }, }, }, } })
src/index.ts内容
import DemoComponent from '@/components/DemoComponent.vue' export { DemoComponent }
package.json配置
{ "name": "@test/example-package", "version": "0.0.1", "type": "module", "files": [ "dist" ], "main": "./dist/example-package.umd.cjs", "module": "./dist/example-package.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/example-package.js", "require": "./dist/example-package.umd.cjs" }, "./dist/style.css": "./dist/style.css" }, "scripts": { "dev": "vite", "build": "vue-tsc --noEmit && vite build", "preview": "vite preview", "test:unit": "vitest", "build-only": "vite build", "type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore --max-warnings=0", "prepare": "husky install" }, // ... }
我通过npm run build && npm pack命令构建项目,请问遗漏了什么配置?
修正build命令,让vue-tsc生成类型文件
原build命令中的vue-tsc --noEmit不会生成.d.ts类型文件,需要去掉--noEmit参数,改为:"build": "vue-tsc && vite build"这样vue-tsc会先完成类型检查并生成组件的类型定义文件,供后续vite-plugin-dts整合。
优化vite-plugin-dts配置
调整vite.config.js中的dts插件配置,确保它正确识别并处理Vue组件的类型:dts({ include: ['src/**/*.vue', 'src/**/*.ts'], // 指定要处理的文件 outputDir: 'dist', // 输出目录与build一致 insertTypesEntry: true, // 自动生成入口类型文件 staticImport: true // 确保类型导入为静态形式 })检查生成的类型文件
构建完成后,查看dist/index.d.ts文件,确认是否包含组件的完整props类型定义,正确的内容应该类似:import type { DefineComponent } from 'vue'; export declare const DemoComponent: DefineComponent<{ example: { type: StringConstructor; required: true; }; }>;如果没有生成该内容,说明vue-tsc或dts插件的配置仍有问题,需要排查。
改用defineProps的TS泛型语法(推荐)
将组件中的defineProps改为TypeScript泛型写法,这种方式更符合TS类型系统,也能让类型生成更准确:<script setup lang="ts"> const props = defineProps<{ example: string // 非可选属性默认即为必填 }>() </script>这种写法无需手动声明
required: true,TS会自动识别为必填属性,编辑器提示更精准。
内容的提问来源于stack exchange,提问作者H. Müller

