您的位置:首页 > 汽车 > 时评 > vue3第三十九节(TS中的高级类型,分类以及使用注意事项)

vue3第三十九节(TS中的高级类型,分类以及使用注意事项)

2024/7/7 16:10:57 来源:https://blog.csdn.net/weixin_39593730/article/details/139637867  浏览:    关键词:vue3第三十九节(TS中的高级类型,分类以及使用注意事项)

前言:为什么需要使用高级类型,正常的类型不能满足日常的业务需求,对于复杂的数据结构、函数签名、类型转换,我们需要使用高级类型来处理,常用的高级类型包含以下几种:
在这里插入图片描述

常用的类型定义
基本类型: 像 number、string、boolean 这样的基本类型,它们表示简单的数据。
对象类型: 可以使用对象字面量、接口、类等定义对象类型。

数组和元组: 具有内置的数组类型和元组类型,用于处理集合数据。

函数类型: 支持函数类型,包括参数类型和返回值类型。

1、交叉类型

是通过 & 符号,将多个类型或者方法合并为一个类型

如:
type Age = {age: number}
type Name = {name: string}
type job = stringtype Person = age & name & job此时 Person 包含了 age name job 的类型

使用于对象合并场景,比如声明一个函数,将两个对象合并为一个对象

<script lang="ts">function extend<T, U>(first:T, second:U): T&U {let result:<T & U> = {}for(let i in first) {result[i] = first[i]}for(let i in second) {if (!result.hasOwnProperty(i)) {result[i] = second[i]}}return result}
</script>

2、联合类型

表示一个值可以是多个类型 中的任意一个,通常使用 | 管道符 表示

type Result = number | string | boolean  
Result 的值只能是  number、string、boolean 中的一个,不能同时是两种或多种

3、映射类型

通过 in 关键字做类型的映射,遍历已有类型的key,或者遍历联合类型,通常与泛型一起使用,用于添加修改属性

<script lang="ts">
type Item = {readonly id: string,title:string
}type ReadOnlyItem<T> = {reaonly [key in keyof T]: T[key]
}type NewItem = ReadOnlyItem<Item>// 获取我们希望 自定义的类型在 使用时候是可选的
type Partial<T> = {[P in keyof T]?: T[P];
}
</script>

keyof T:通过类型索引 keyof 的得到联合类型 id | title
P in keyof T 等同于 p in id | title,相当于执行了一次 forEach 的逻辑,遍历 id | title, 从而进行修改获取最新的类型
最后得到的 NewItem为如下:

type NewItem =  {readonly id: string,readonly title:string
}

4、条件类型

条件类型允许通过 三元运算的方式 选择不同的类型,通常应用于泛型或者复杂类型

<script lang="ts">T extend U ? E : F // 如果 T是U的子集,那么就取 泛型 E 否则 取 泛型 F// 如定义一个booleantype IsBoolean<T> = T extend boolean ? true : falsetype E = isBoolean<string> // falsetype F = isBoolean<boolean> // true</script>

5、可辨识联合类型

在函数式编程中 我们通常会合并单例类型联合类型类型保护类型别名来创建一个叫做 可辨识联合的高级模式,它也称做 标签联合代数数据类型
通常需要满足 三个要素
A、具有普通的单例类型属性— 可辨识的特征
B、一个类型别名包含了那些类型的联合— 联合
C、此属性上的类型保护

<script lang="ts">
interface Square {kind: "square";size: number;
}
interface Rectangle {kind: "rectangle";width: number;height: number;
}
interface Circle {kind: "circle";radius: number;
}
// 先声明 三个接口。 每个接口都有 kind属性但有不同的字符串字面量类型。 kind属性称做 可辨识的特征或 标签。 其它的属性则特定于各个接口;
type Shape = Square | Rectangle | Circle;
// 现在我们使用可辨识联合:function area(s: Shape) {switch (s.kind) {case "square": return s.size * s.size; // 正方形面积case "rectangle": return s.height * s.width;case "circle": return Math.PI * s.radius ** 2;}
}// 若我们没有涵盖所有可辨识的类型时,我们希望编译器能够告知我们
// 使用 never 类型 做完整检查
function areaNever(x: never):never {throw new Error("Unexpected object:  " + x + "in Area")
}
// area 做如下修改
function area(s: Shape) {switch (s.kind) {case "square": return s.size * s.size; // 正方形面积case "rectangle": return s.height * s.width;case "circle": return Math.PI * s.radius ** 2;default: return areaNever(s)}
}
</script>

6、索引类型

keyof 类似于 Object.keys ,用于获取一个接口中 Key 的联合类型。

<script lang="ts">
interface Button {type: stringtext: string
}type ButtonKeys = keyof Button
// 等效于
type ButtonKeys = "type" | "text"
</script>

7、类型别名

类型别名会给类型起一个新的名字,可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型;起别名是新建一个名字,由于引用那个类型;
可以使用 type SomeName = someValidTypeAnnotation的语法来创建类型别名

<script lang="ts">type age = number | stringconst b: age = true // 不能将类型 true分配给类型“some”const c: age = 'hello' // okconst d: age = 123 // ok// 泛型type Container<T> = { value: T };// 使用类型别名在属性中引用自己type Tree<T> = {value: T;left: Tree<T>;right: Tree<T>;}
</script>

8、类型约束

通过关键字 extend 进行约束,不同于在 class 后使用 extends 的继承作用,泛型内使用的主要作用是对泛型加以约束

<script>
type BaseType = string | number | boolean
// 这里表示 copy 的参数
// 只能是字符串、数字、布尔这几种基础类型
function copy<T extends BaseType>(arg: T): T {return arg
}
</script>

类型约束通常和类型索引一起使用,例如我们有一个方法专门用来获取对象的值,但是这个对象并不确定,我们就可以使用 extends 和 keyof 进行约束。

<script>function getValue<T, K extends keyof T>(obj: T, key: K) {return obj[key]}const obj = { a: 1 }const a = getValue(obj, 'a')
</script>

TypeScript 的高级类型是前端开发中的强大工具,可以帮助我们处理复杂的数据结构构建类型安全的应用程序和提高代码的可维护性。通过进一步学习交叉类型、联合类型、映射类型、条件类型等,我们可以更好地应用它们在实际项目中

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com