tsvue-dts
v0.0.1
Published
这是一个基于 `ts-morph` 和 `@vue/compiler-sfc` 的工具,用于从 Vue 3 项目中自动提取和生成 TypeScript 类型声明文件。该工具能够解析 Vue 单文件组件(SFC)中的 `<script setup>` 语法,提取 Props、Emits 等类型信息,支持提取非vue的ts类型,并生成统一的类型声明文件。
Readme
Vue TypeScript 类型声明生成器
项目简介
这是一个基于 ts-morph 和 @vue/compiler-sfc 的工具,用于从 Vue 3 项目中自动提取和生成 TypeScript 类型声明文件。该工具能够解析 Vue 单文件组件(SFC)中的 <script setup> 语法,提取 Props、Emits 等类型信息,支持提取非vue的ts类型,并生成统一的类型声明文件。
功能特性
🎯 核心功能
- Vue 组件类型提取:自动解析
.vue文件中的<script setup>语法 - Props 类型生成:从
defineProps中提取属性类型定义 - Emits 类型生成:从
defineEmits中提取事件类型定义 - 单文件输出:将所有类型声明聚合到一个
index.d.ts文件中 - 类型兼容性:保持与原始导出的完全兼容
🔧 高级特性
- 选项式组件支持:解析传统 Vue 选项式组件的 data、computed、methods 类型
- 类型别名提取:自动提取组件中定义的类型别名和接口
- 智能类型推断:从
this.$emit调用中推断事件类型 - 依赖解析:基于入口文件自动解析依赖关系
- 命名冲突避免:使用随机后缀避免本地类型命名冲突
技术架构
依赖库
- ts-morph:TypeScript AST 操作和类型检查
- @vue/compiler-sfc:Vue 单文件组件解析
- Node.js fs/path:文件系统操作
使用方法
基本用法
- 安装依赖
npm install tsvue-dts- 配置入口文件
// src/entry.ts
export { default as MyButton } from './components/MyButton.vue'
export { default as MyInput } from './components/MyInput.vue'
export { type ButtonProps, type InputProps } from './components/types'- 运行生成器
npx tsvue-dts- 输出结果
// types/index.d.ts
import type { DefineComponent } from 'vue'
// 自动生成的类型声明
type MyButtonProps_abc123 = {
size?: 'small' | 'medium' | 'large'
disabled?: boolean
}
interface MyButtonEmits_abc123 {
(e: 'click', event: MouseEvent): void
(e: 'change', value: string): void
}
export declare const MyButton: DefineComponent<MyButtonProps_abc123, any, any, any, any, any, any, MyButtonEmits_abc123>支持的语法
Vue 3 Composition API
<script setup lang="ts">
// Props 类型定义
interface ButtonProps {
size?: 'small' | 'medium' | 'large'
disabled?: boolean
}
// Emits 类型定义
interface ButtonEmits {
(e: 'click', event: MouseEvent): void
}
const props = defineProps<ButtonProps>()
const emit = defineEmits<ButtonEmits>()
</script>选项式组件
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
data() {
return {
count: 0,
message: 'Hello'
}
},
computed: {
doubleCount(): number {
return this.count * 2
}
},
methods: {
increment(): void {
this.count++
this.$emit('update', this.count)
}
}
})
</script>输出格式
类型声明结构
// 1. 组件 Props 类型
type ComponentNameProps = { ... }
// 2. 组件 Emits 类型
interface ComponentNameEmits { ... }
// 3. 组件 Data 类型
type ComponentNameData = { ... }
// 4. 组件 Computed 类型
type ComponentNameComputed = { ... }
// 5. 组件 Methods 类型
type ComponentNameMethods = { ... }
// 6. 组件声明
export declare const ComponentName: DefineComponent<Props, RawBindings, Data, Computed, Methods, Mixins, Extends, Emits>类型导出
// 支持类型别名导出
export type ButtonProps = MyButtonProps_abc123
export type ButtonEmits = MyButtonEmits_abc123配置选项
TypeScript 配置
工具会自动生成 tsconfig.entry.json 配置文件,包含以下设置:
- 继承
@vue/tsconfig/tsconfig.dom.json - 启用严格模式
- 支持 Vue 单文件组件
- 仅生成声明文件
编译选项
{
"declaration": true,
"emitDeclarationOnly": true,
"declarationMap": false,
"noEmit": false
}注意事项
限制条件
- 单文件输出:所有类型声明聚合到一个文件中
- 命名冲突:使用随机后缀避免本地类型命名冲突
- 依赖解析:仅处理入口文件直接导出的组件
- 类型推断:部分复杂类型可能无法完全推断
最佳实践
- 统一命名:使用 PascalCase 命名组件和类型
- 类型导出:在入口文件中明确导出需要的类型
- JSDoc 注释:为类型添加文档注释
- 类型安全:使用严格的 TypeScript 配置
故障排除
常见问题
类型提取失败
- 检查 Vue 组件语法是否正确
- 确认 TypeScript 配置是否支持 Vue 文件
依赖解析错误
- 检查入口文件路径是否正确
- 确认所有依赖文件存在
类型冲突
- 检查是否有重复的类型名称
- 使用不同的类型名称避免冲突
