TypeScript的高级类型

Typescript中的高级类型指的是对类型的高级操作得到的类型称为高级类型。包括交叉类型、联合类型、索引类型、映射类型、条件类型。

交叉类型

将多个类型合并为一个类型,可以用于对象混入。使用&符号连接

interface DogInterface{
	run():void
}

interface CatInterface{
	jump():void
}
let pet:DogInterface & CatInterface={
	run(){},
	jump(){}
}

交叉类型具有每一个类型的方法和属性

联合类型

联合类型由一组有序的成员类型构成。联合类型表示一个值的类型可以为若干种类型之一。使用 | 分隔各个类型。

let name :string|number="Mr.Lee" //这表示name可以是string类型或者是number类型的值

联合类型的成员类型可以为任意类型,如原始类型、数组类型、对象类型,以及函数类型等。

type T = boolean | string[] | { x: number } | (() => void);

如果联合类型中存在相同的成员类型,那么相同的成员类型将被合并为单一成员类型。

type T0 = boolean;                     // boolean
type T1 = boolean | boolean;           // boolean

type T2 = boolean | string;            // boolean | string
type T3 = boolean | string | boolean;  // boolean | string

联合类型是有序的成员类型的集合。在绝大部分情况下,成员类型满足类似于数学中的“加法交换律”,即改变成员类型的顺序不影响联合类型的结果类型。

type T0 = string | number;
type T1 = number | string;

联合类型中的类型成员同样满足类似于数学中的“加法结合律”。对部分类型成员使用分组运算符不影响联合类型的结果类型。

type T0 = (boolean | string) | number;
type T1 = boolean | (string | number);

联合类型的成员类型可以进行化简。假设有联合类型“U = T0 | T1”,如果T1是T0的子类型,那么可以将类型成员T1从联合类型U中消去。最后,联合类型U的结果类型为“U = T0”。

// 'true' 和 'false' 类型是 'boolean' 类型的子类型
type T0 = boolean | true | false;

// 所以T0等同于 T1
type T1 = boolean;

可区分的联合类型

一个变量如果是多个类型的联合类型,并且具有共有属性,那么就可以用共有属性创建不同的类型保护区块,这样也可以区分不同的类型。

interface Square{
	kind:"square"
	size:number
}
interface Rectangle{
	kind:"rectangle"
	width:number
	height:number
}
interface Circle{
	kind:"circle"
	r:number
}
type Shape=Square|Rectangle|Circle
function area(s:Shape){
	switch(s.kind){
		case "square":
			return s.size=s.size;
			break;
		case "rectangle":
			return s.height=s.width;
			break;
		case "circle":
			return Math.PI*s.r**2
		default :
		return ((e:never)=>{throw new Error(e)})(s)//该函数的作用为判断s的类型是否为never类型如果是那么上面的分支情况都考虑到了,如果不是never类型那么上面的分支有遗漏
	}
}
console.log(area({kind:"circle",r:1}))

字面量类型

可以把一个字面量的值作为一种类型叫做字面量类型
一般情况下,声明一个name变量会以以下方式进行赋值

let name :string = "Mr.Lee" //这表示name可以是任意string类型的值

如果我们想指定该变量为某一特定字符串的值,会以以下方式

let name:"Mr.Lee"= "Mr.Lee" // 这表示name的值只能是"Mr.Lee"

如果我们将name的值改为另一个字符串

let nam:"Mr.Lee"="Mr.M";

在这里插入图片描述

索引类型

索引类型的查询操作符

keyof T//表示类型T的所有公共属性的字面量的联合类型

interface Obj{
	a:number
	b:number
}
let key : keyof Obj//key的类型就是字面量'a'|'b'的联合类型

索引类型查询的结果是由字符串字面量类型构成的联合类型,该联合类型中的每个字符串字面量类型都表示一个属性名类型。

JavaScript中的对象是键值对的数据结构,它只允许将字符串和Symbol值作为对象的键。索引类型查询获取的是对象的键的类型,因此索引类型查询的结果类型是联合类型“string | symbol”的子类型,因为只有这两种类型的值才能作为对象的键。但由于数组类型十分常用且其索引值的类型为number类型,因此编译器额外将number类型纳入了索引类型查询的结果类型范围。于是,索引类型查询的结果类型是联合类型“string | number | symbol”的子类型,这是编译器内置的类型。

keyof的运算过程
  1. 如果类型T中包含字符串索引签名,那么将string类型和number类型添加到结果类型KeyofT。
  2. 如果类型T中包含数值索引签名,那么将number类型添加到结果类型KeyofT。
  3. 如果类型T中包含属性名类型为“unique symbol”的属性,那么将该“unique symbol”类型添加到结果类型KeyofT。
  4. 最后,如果类型T中包含其他属性成员,那么将表示属性名的字符串字面量类型和数字字面量类型添加到结果类型KeyofT。

索引访问操作符

T[value]//对象T的属性key所代表的类型
interface Obj{
	a:number
	b:number
}
let value:Obj[a]//表示Obj的属性a所代表的类型,a的类型为number因此value的类型为number

映射类型

interface Obj{
	a:string
	b:number
	c:boolean
}
type ReadonlyObj = Readonly<Obj>

这样就把Obj中的属性变为只读类型

interface Obj{
	a:string
	b:number
	c:boolean
}
type partialType = partial<Obj>

将Obj中的所有属性变成可选的。

实现原理
type Readonly<T>={
	readonly [P in keyof T]:T[P];
}

Readonly是一个可索引的泛型接口,keyof T 索引类型的查询操作符,表示T的所有属性的联和类型,p in 相当于执行for……in循环操作,把变量P依次绑定到T的所有属性上,T[P]是索引类型的索引访问操作符,代表T的属性P代表的类型,然后通过readonly修饰符,将属性变为只读

条件类型

由条件表达式所决定的类型,增加了变量类型的灵活性和不唯一性

//T extends U?X:Y;如果类型T可以被复制给类型U结果类型就是X类型否则就是Y类型
type TypeName<T>=
T extends string ? "string" : 
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T1 = TypeName<string[]>//object类型
type T2 = TypeName<string>//string类型
type T3 = TypeName<string | string[]>//string类型和objec类型的联和类型
type Diff<T,U>=T extends U ? never : T
let T4 = Diff<"a" | "b" | "c","a" | "b">
//Diff<"a","a" | "b"> | Diff<"b","a" | "b"> | Diff<"c","a" | "b">
//"never" | "b" | "c"
//"b" | "c"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值