详解TypeScript使用及类型声明文件

目录
  • 简介
  • Script 与 Vue3
    • defineProps 与 Typescript
    • defineEmits 与 Typescript
    • ref 与 Typescript
    • computed 与 Typescript
    • 事件对象 与 Typescript
    • 模板 Ref 与 Typescript
    • 可选链操作符
    • 非空断言-TS
  • TypeScript类型声明文件
    • 基本介绍
    • 内置类型声明文件
    • 第三方库类型声明文件
    • 自定义类型声明文件

简介

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

为什么需要声明文件呢?我们知道TypeScript根据类型声明进行类型检查,但有些情况可能没有类型声明:

  • 第三方包,因为第三方包打包后都是JavaScript语法,而非TypeScript,没有类型。
  • 宿主环境扩展,如一些hybrid环境,在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使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Typescript文件被识别为视频的问题解决

    目录 概念引入 问题现象 解决办法 恢复视频模式 概念引入 TypeScript 是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成 Transport Stream 即传输流,是一种常见的视频封装格式,基于MPEG-2的封装格式(所以也叫MPEG-TS) TypeScript和Transport Stream的文件扩展名均为ts 问题现象 在Windows操作系统上.ts被默认标记为Transport Stream,对于普通用户来讲这完全没有问题,但对于

  • 如何在TypeScript中处理日期字符串

    目录 前言: 一.模板字面量类型 二.类型谓词缩小范围 三.定义日期字符串 总结: 前言: 在我最近的一个项目中,我必须去处理多个自定义的日期字符串表示法,比如YYYY-MM-DD和YYYYMMDD.由于这些日期是字符串变量,TypeScript默认会推断成为string类型.虽然这在技术实现上没有错,但是在工作中使用这样的类型定义是很宽泛的,使得有效处理这些日期字符串变得很困难.例如,let dog = 'alfie'也被推断为一个string类型. 在这篇文章中,我会将我的解决方法呈现给你,

  • TypeScript函数和类型断言实例详解

    目录 开始 断言 非空断言 类型断言 尖括号 as 确定赋值断言 类型守卫 trpeof in 函数 可选参数 默认值参数 函数重载 结束 开始 现在要加速学习了,大佬们有没有内推,给个推荐 会vue2/vue3 + ts 断言 非空断言 非空断言就是确定这个变量不是null或者undefined,就是把null或者undefined从他的类型中排除 function demo(message:string|undefined|null) { const str: string = messag

  • TypeScript 使用 Tuple Union 声明函数重载

    问题: TypeScript 中为函数添加多个签名后,依然需要添加相应的代码来判断并从不同的签名参数列表中获取对应的参数.过去常见的写法: function refEventEmitter(event?: string): void; function refEventEmitter(event: string, callback: () => void): void; function refEventEmitter(callback: () => void): void; function

  • TypeScript调整数组元素顺序算法

    目录 前言 实现思路 实现代码 代码的可扩展性 测试用例 示例代码 总结 前言 有一个整数数组,我们想按照特定规则对数组中的元素进行排序,比如:数组中的所有奇数位于数组的前半部分. 本文将带大家实现这个算法,欢迎各位感兴趣的开发者阅读本文. 实现思路 我们通过一个实例来分析下:假设有这样一个数组:[2, 4, 5, 6, 7, 8, 9, 11],将奇数移动到最前面后,就是:[11, 9, 5, 7, 6, 8, 4, 2]. 通过观察后,我们发现在扫描这个数组的时候,如果发现有偶数出现在奇数的

  • 详解TypeScript使用及类型声明文件

    目录 简介 Script 与 Vue3 defineProps 与 Typescript defineEmits 与 Typescript ref 与 Typescript computed 与 Typescript 事件对象 与 Typescript 模板 Ref 与 Typescript 可选链操作符 非空断言-TS TypeScript类型声明文件 基本介绍 内置类型声明文件 第三方库类型声明文件 自定义类型声明文件 简介 声明文件是以.d.ts为后缀的文件,开发者在声明文件中编写类型声明

  • 详解TypeScript中的类型保护

    概述 在 TypeScript 中使用联合类型时,往往会碰到这种尴尬的情况: interface Bird { // 独有方法 fly(); // 共有方法 layEggs(); } interface Fish { // 独有方法 swim(); // 共有方法 layEggs(); } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 正常 pet.swim();

  • 详解TypeScript的基础类型

    目录 布尔类型 数字类型 字符串类型 字符串和数字进行拼接 undefined和 null 数组类型 元组类型 枚举类型 any类型 void类型 联合类型 总结 布尔类型 // 布尔类型--->boolean // let 变量名:数据类型 = 值 let flag: boolean = true; console.log(flag) 数字类型 // 数字类型--->number let a1: number = 10 // 十进制 let a2: number = 0b1010 // 二进

  • 详解TypeScript映射类型和更好的字面量类型推断

    概述 TypeScript 2.1 引入了映射类型,这是对类型系统的一个强大的补充.本质上,映射类型允许w咱们通过映射属性类型从现有类型创建新类型.根据咱们指定的规则转换现有类型的每个属性.转换后的属性组成新的类型. 使用映射类型,可以捕获类型系统中类似Object.freeze()等方法的效果.冻结对象后,就不能再添加.更改或删除其中的属性.来看看如何在不使用映射类型的情况下在类型系统中对其进行编码: interface Point { x: number; y: number; } inte

  • 详解 TypeScript 枚举类型

    目录 1. 数字枚举 2. 字符串枚举 3. 反向映射 4. 异构枚举 5. 常量枚举 6. 枚举成员类型和联合枚举类型 (1)枚举成员类型 (2)联合枚举类型 7. 枚举合并 前言: TypeScript 在 ES 原有类型基础上加入枚举类型,使得在 TypeScript 中也可以给一组数值赋予名字,这样对开发者比较友好,可以理解枚举就是一个字典. 枚举类型使用enum来定义: enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, F

  • 详解C 语言项目中.h文件和.c文件的关系

    详解C 语言项目中.h文件和.c文件的关系 在编译器只认识.c(.cpp))文件,而不知道.h是何物的年代,那时的人们写了很多的.c(.cpp)文件,渐渐地,人们发现在很多.c(.cpp)文件中的声明语句就是相同的,但他们却不得不一个字一个字地重复地将这些内容敲入每个.c(.cpp)文件.但更为恐怖的是,当其中一个声明有变更时,就需要检查所有的.c(.cpp)文件. 于是人们将重复的部分提取出来,放在一个新文件里,然后在需要的.c(.cpp)文件中敲入#include XXXX这样的语句.这样即

  • 详解Typescript里的This的使用方法

    this可以说是Javascript里最难理解的特性之一了,Typescript里的 this 似乎更加复杂了,Typescript里的 this 有三中场景,不同的场景都有不同意思. this 参数: 限制调用函数时的 this 类型 this 类型: 用于支持链式调用,尤其支持 class 继承的链式调用 ThisType: 用于构造复杂的 factory 函数 this 参数 由于 javascript 支持灵活的函数调用方式,不同的调用场景,this 的指向也有所不同 作为对象的方法调用

  • 详解TypeScript中type与interface的区别

    目录 类型别名 type 接口 interface interface和type的相似之处 都可以描述 Object和Function Type Interface 二者都可以被继承 interface 继承 interface interface 继承 type type 继承 type type 继承 interface 实现 implements 二者区别 1. 定义基本类型别名 2. 声明联合类型 3. 声明元组 4. 声明合并 5. 索引签名问题 总结 类型别名 type 首先认识一下

  • 详解Typescript 严格模式有多严格

    目录 正文 noImplicitAny noImplicitThis alwaysStrict strictBindCallApply strictNullChecks strictPropertyInitialization strictFunctionTypes 正文 TypeScript 是微软于 2012 年推出的一门语言,它是 JavaScript 的超集,具有更强的可选类型系统.TypeScript 和 JavaScript 一样是有严格模式的,今天就来看看 TypeScript 中

  • 一文详解typeScript的extends关键字

    目录 前言 extends 的几个语义 extends 与 类型组合/类继承 extends 与类型约束 extends 与条件类型 extends 与 {} extends 与 any extends 与 never extends 与 联合类型 extends 判断类型严格相等 extends 与类型推导 总结 前言 声明: 以下文章所包含的结论都是基于 typeScript@4.9.4 版本所取得的. extends 是 typeScript 中的关键字.在 typeScript 的类型编

随机推荐