TypeScript类型声明文件详解与Vue3实战指南

作者:小括号时间:2026-10-26 02:11:12浏览:146

本文详解TypeScript类型声明文件(.d.ts)的定义与作用,涵盖内置API、第三方库及自定义声明。结合Vue3 Composition API,深入讲解defineProps、defineEmits、ref、computed及DOM操作中的类型校验技巧,并介绍可选链与非空断言语法。

概述

类型声明文件采用.d.ts扩展名,开发者在其中定义类型规范,TypeScript依据这些规范执行类型校验。需留意同目录下避免存在同名.ts与.d.ts文件(如lib.ts与lib.d.ts),以免模块系统因文件名无法正确加载模块。

为何需要类型声明文件?尽管TypeScript依赖类型声明进行校验,但部分场景下缺乏类型声明:

  • 第三方依赖包,因其打包后为JavaScript语法而非TypeScript,故无类型信息。
  • 宿主环境扩展,例如某些混合环境在window变量下提供的bridge接口,此类接口缺乏类型声明。

Script与Vue3

参考链接(英文):vuejs.org/guide/types…

参考链接(中文):staging-cn.vuejs.org/guide/types…

在vue3结合ts使用时,需额外安装vscode插件:Typescript Vue Plugin

概述

defineProps与Typescript

目标:理解defineProps如何与ts协同工作

  • defineProps结合vue默认语法进行类型校验(运行时声明)
// 运行时声明
defineProps({
  money: {
    type: Number,
    required: true
  },
  car: {
    type: String,
    required: true
  }
})
  • defineProps结合ts的泛型定义props类型校验,这种方式更为直观
// 使用 ts 的泛型指定 props 类型
defineProps<{
  money: number
  car?: string
}>()
  • props可通过解构方式指定默认值
<script lang="ts" setup>
// 使用ts的泛型指令props类型
const { money, car = '小黄车' } = defineProps<{
  money: number
  car?: string
}>()
</script>

若提供的默认值需在模板中渲染,需额外添加配置

vuejs.org/guide/extra…

// vite.config.js
export default {
  plugins: [
    vue({
      reactivityTransform: true
    })
  ]
}

defineEmits与Typescript

目标:理解defineEmits如何与ts协同工作

  • defineEmits结合运行时声明
const emit = defineEmits(['change', 'update'])
  • defineEmits结合ts类型声明,可实现更精细的校验
const emit = defineEmits<{
  (e: 'changeMoney', money: number): void
  (e: 'changeCar', car: string): void
}>()

ref与Typescript

目标:理解ref如何与ts协同工作

  • 通过泛型指定value的值类型,若为简单值,该类型可省略
const money = ref<number>(10)
// 推荐写法,提供效率
const money = ref(10)
  • 若为复杂类型,需通过泛型指定
interface Todo {
  id: number
  content: string
  done: boolean
}
// 复杂类型需要指定结构,不能省略
const list = ref<Todo[]>([])
list.value.push({ id: 1, content: '吃饭', done: false })

computed与Typescript

目标:理解computed如何与typescript协同工作

  • 通过泛型可指定computed计算属性的类型,通常可省略
const leftCount = computed<number>(() => {
  return list.value.filter((v) => v.done).length
})
console.log(leftCount.value)

事件对象与Typescript

目标:理解事件处理函数如何与typescript协同工作

const btn = (e: MouseEvent) => {
  mouse.value.x = e.pageX
  mouse.value.y = e.pageY
}
<h2 @click="btn($event)">根组件</h2>

模板Ref与Typescript

目标:理解ref操作DOM时如何与Typescript协同工作

const imgRef = ref<HTMLImageElement | null>(null)
onMounted(() => {
  console.log(imgRef.value?.src)
})

查看DOM对象类型的方法:通过控制台进行查看

document.createElement('img').__proto__

可选链操作符

**目标:**理解js中提供的可选链操作符语法

内容

  • 可选链操作符( ?. )允许读取连接对象链深处属性的值,无需明确验证链中每个引用是否有效。
  • 参考文档:developer.mozilla.org/zh-CN/docs/…
let nestedProp = obj.first?.second;
console.log(res.data?.data)
obj.fn?.()

if (obj.fn) {
    obj.fn()
}
obj.fn && obj.fn()

// 等价于
let temp = obj.first;
let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);

非空断言-TS

目标:理解ts中非空断言的使用语法

内容:

  • 若明确知道对象属性绝不会为空,可使用非空断言 !
// 告诉 typescript, 明确的指定obj不可能为空
let nestedProp = obj!.second;
  • 注意:使用非空断言前务必确保属性存在,否则会导致bug

TypeScript类型声明文件

基本介绍

当今几乎所有JavaScript应用均引入众多第三方库以满足需求。无论这些库是否由TS编写,最终均需编译为JS代码方可发布给开发者使用。已知TS提供了类型,从而实现了代码提示和类型保护等机制。

但在项目开发中使用第三方库时,会发现它们几乎均具备相应的TS类型,这些类型源自何处?类型声明文件

  • 类型声明文件:用于为已存在的JS库提供类型信息

  • TS中包含两种文件类型:1 .ts 文件 2 .d.ts 文件

  • .ts 文件:

    既包含类型信息又可执行代码

    可编译为.js文件,随后执行代码

    用途:编写程序代码之处

  • .d.ts 文件:

    只包含类型信息的类型声明文件

    不生成.js文件,仅用于提供类型信息,.d.ts文件中不允许出现可执行代码,仅用于提供类型

    用途:为JS提供类型信息

  • 总结:.ts 是 implementation(代码实现文件);.d.ts 是 declaration(类型声明文件)

  • 若需为JS库提供类型信息,应使用 .d.ts 文件

内置类型声明文件

  • TS为JS运行时可用的所有标准化内置API均提供了声明文件
  • 例如,使用数组时,数组所有方法均具备相应的代码提示及类型信息:
const strs = ['a', 'b', 'c']
// 鼠标放在 forEach 上查看类型
strs.forEach
  • 实际上这均由TS提供的内置类型声明文件实现
  • 可通过Ctrl + 鼠标左键(Mac:Command + 鼠标左键)查看内置类型声明文件内容
  • 例如,查看forEach方法的类型声明,在VSCode中会自动跳转至 lib.es5.d.ts 类型声明文件
  • 当然,像window、document等BOM、DOM API也均具备相应的类型声明(lib.dom.d.ts)

第三方库类型声明文件

  • 目前,几乎所有常用第三方库均具备相应的类型声明文件
  • 第三方库的类型声明文件存在两种形式:1 库自带类型声明文件 2 由DefinitelyTyped提供。
  • 库自带类型声明文件:例如,axios
  • 查看 node_modules/axios 目录

解释:此种情况下,正常导入该库,TS即会自动加载库自身的类型声明文件,以提供该库的类型声明。

  • 由DefinitelyTyped提供
  • DefinitelyTyped是一个github仓库,用于提供高质量TypeScript类型声明
  • DefinitelyTyped链接
  • 可通过npm/yarn下载该仓库提供的TS类型声明包,这些包的名称格式为:@types/*
  • 例如,@types/react、@types/lodash等
  • 说明:在实际项目开发时,若使用的第三方库无自带声明文件,VSCode会给出明确提示
import _ from 'lodash'
// 在 VSCode 中,查看 'lodash' 前面的提示
  • 解释:当安装 @types/* 类型声明包后,TS亦会自动加载该类声明包,以提供该库的类型声明
  • 补充:TS官方文档提供了一个页面,可用于查询@types/*库
  • @types/*库

自定义类型声明文件

项目内共享类型

  • 若多个.ts文件均使用同一类型,此时可创建.d.ts文件提供该类型,实现类型共享。
  • 操作步骤:

    创建index.d.ts类型声明文件。

    创建需共享的类型,并使用export导出(TS中的类型亦可使用import/export实现模块化功能)。

    在需使用共享类型的.ts文件中,通过import导入即可(.d.ts后缀导入时,直接省略)。

为已有JS文件提供类型声明

  • 在将JS项目迁移至TS项目时,为使已有的.js文件具备类型声明。
  • 成为库作者,创建库供他人使用。
  • 演示:基于最新的ESModule(import/export)为已有.js文件,创建类型声明文件。

类型声明文件的使用说明

  • 说明:TS项目中亦可使用.js文件。
  • 说明:在导入.js文件时,TS会自动加载与.js同名的.d.ts文件,以提供类型声明。
  • declare关键字:用于类型声明,为其他地方(例如,.js文件)已存在的变量声明类型,而非创建新变量。

    对于type、interface等明确属于TS类型的(仅能在TS中使用),可省略declare关键字。

    对于let、function等具有双重含义(在JS、TS中均能用),应使用declare关键字,明确指定此处用于类型声明。

let count = 10
let songName = '痴心绝对'
let position = {
  x: 0,
  y: 0
}
function add(x, y) {
  return x + y
}
function changeDirection(direction) {
  console.log(direction)
}
const fomartPoint = point => {
  console.log('当前坐标:', point)
}
export { count, songName, position, add, changeDirection, fomartPoint }

定义类型声明文件

declare let count:number
declare let songName: string
interface Position {
  x: number,
  y: number
}
declare let position: Position
declare function add (x :number, y: number) : number
type Direction = 'left' | 'right' | 'top' | 'bottom'
declare function changeDirection (direction: Direction): void
type FomartPoint = (point: Position) => void
declare const fomartPoint: FomartPoint
export {
  count, songName, position, add, changeDirection, FomartPoint, fomartPoint
}

至此关于TypeScript使用以及类型声明文件的文章介绍完毕,更多相关TypeScript使用内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

作者最新文章
相关文章
更多