You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+TypeScript组件npm包未导出类型检查,编辑器无必填属性提示

问题:Vue3组件发布为npm包后,必填属性的TypeScript编辑器提示丢失

我用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:47:06