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”的子类型,这是编译器内置的类型。
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"