声明文件是以.d.ts为后缀的文件,开发者在声明文件中编写类型声明,TypeScript根据声明文件的内容进行类型检查。(注意同目录下最好不要有同名的.ts文件和.d.ts,例如lib.ts和lib.d.ts,否则模块系统无法只根据文件名加载模块)

为什么需要声明文件呢?我们知道TypeScript根据类型声明进行类型检查,但有些情况可能没有类型声明:
参考链接(英文):vuejs.org/guide/types…
参考链接(中文):staging-cn.vuejs.org/guide/types…
vue3配合ts中,还需要额外安装一个 vscode 插件:Typescript Vue Plugin
目标:掌握defineProps如何配合ts使用
// 运行时声明
defineProps({
money: {
type: Number,
required: true
},
car: {
type: String,
required: true
}
})
// 使用 ts 的泛型指定 props 类型
defineProps<{
money: number
car?: string
}>()
<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 如何配合ts使用
const emit = defineEmits(['change', 'update'])
const emit = defineEmits<{
(e: 'changeMoney', money: number): void
(e: 'changeCar', car: string): void
}>()
目标:掌握ref配合ts如何使用
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如何使用
const leftCount = computed<number>(() => {
return list.value.filter((v) => v.done).length
})
console.log(leftCount.value)
目标:掌握事件处理函数配合typescript如何使用
const btn = (e: MouseEvent) => {
mouse.value.x = e.pageX
mouse.value.y = e.pageY
}
<h2 @click="btn($event)">根组件</h2>
目标:掌握ref操作DOM时如何配合Typescript使用
const imgRef = ref<HTMLImageElement | null>(null)
onMounted(() => {
console.log(imgRef.value?.src)
})
如何查看一个DOM对象的类型:通过控制台进行查看
document.createElement('img').__proto__
**目标:**掌握js中的提供的可选链操作符语法
内容
?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。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中的非空断言的使用语法
内容:
!// 告诉 typescript, 明确的指定obj不可能为空 let nestedProp = obj!.second;
今天几乎所有的 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 文件
const strs = ['a', 'b', 'c'] // 鼠标放在 forEach 上查看类型 strs.forEach
lib.es5.d.ts 类型声明文件中lib.dom.d.ts)node_modules/axios 目录解释:这种情况下,正常导入该库,TS 就会自动加载库自己的类型声明文件,以提供该库的类型声明。
@types/*import _ from 'lodash' // 在 VSCode 中,查看 'lodash' 前面的提示
@types/* 类型声明包后,TS 也会自动加载该类声明包,以提供该库的类型声明项目内共享类型
创建 index.d.ts 类型声明文件。
创建需要共享的类型,并使用 export 导出(TS 中的类型也可以使用 import/export 实现模块化功能)。
在需要使用共享类型的 .ts 文件中,通过 import 导入即可(.d.ts 后缀导入时,直接省略)。
为已有 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
}