类型变换
交叉类型
- 交叉类型(Intersection Types)表示将多个类型合并为一个类型
interface Bird{
name:string,
fly():void
}
interface Person{
name:string,
talk():void
}
type BirdPerson = Bird & Person;
let p:BirdPerson={name:'zhufeng',fly(){},talk(){}};
p.fly;
p.name
p.talk;
typeof
type People = {
name:string,
age:number,
gender:string
}
let p1:People = {
name:'zhufeng',
age:10,
gender:'male'
}
let p1 = {
name:'zhufeng',
age:10,
gender:'male'
}
type People = typeof p1;
function getName(p:People):string{
return p.name;
}
索引访问操作符
interface Person{
name:string;
age:number;
job:{
name:string
};
interests:{name:string,level:number}[]
}
let FrontEndJob:Person['job'] = {
name:'前端工程师'
}
let interestLevel:Person['interests'][0]['level'] = 2;
keyof
interface Person{
name:string;
age:number;
gender:'male'|'female';
}
type PersonKey = keyof Person;
function getValueByKey(p:Person,key:PersonKey){
return p[key];
}
let val = getValueByKey({name:'zhufeng',age:10,gender:'male'},'name');
console.log(val);
映射类型
interface Person{
name:string;
age:number;
gender:'male'|'female';
}
type PartPerson = {
[Key in keyof Person]?:Person[Key]
}
let p1:PartPerson={};
type Part<T> = {
[key in keyof T]?:T[key]
}
let p2:Part<Person>={};
内置工具类型
- TS 中内置了一些工具类型来帮助我们更好地使用类型系统
Partial
type Partial<T> = { [P in keyof T]?: T[P] };
interface A {
a1: string;
a2: number;
a3: boolean;
}
type aPartial = Partial<A>;
const a: aPartial = {};
Required
- Required 可以将传入的属性中的可选项变为必选项,这里用了 -? 修饰符来实现
type Required<T> = { [P in keyof T]-?: T[P] };
interface Person{
name:string;
age:number;
gender?:'male'|'female';
}
let p:Required<Person> = {
name:'zhufeng',
age:10,
}
Readonly
- Readonly 通过为传入的属性每一项都加上 readonly 修饰符来实现。
type Readonly<T> = { readonly [P in keyof T]: T[P] };
interface Person{
name:string;
age:number;
gender?:'male'|'female';
}
let p:Readonly<Person> = {
name:'zhufeng',
age:10,
gender:'male'
}
p.age = 11;
Pick
- Pick 能够帮助我们从传入的属性中摘取某一项返回
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
interface Animal {
name: string;
age: number;
}
type AnimalSub = Pick<Animal, "name">;
映射类型修饰符的控制
- TypeScript中增加了对映射类型修饰符的控制
- 具体而言,一个
readonly 或 ? 修饰符在一个映射类型里可以用前缀 + 或-来表示这个修饰符应该被添加或移除
- TS 中部分内置工具类型就利用了这个特性(Partial、Required、Readonly...),这里我们可以参考 Partial、Required 的实现
条件类型
- 在定义泛型的时候能够添加进逻辑分支,以后泛型更加灵活
定义条件类型
interface Fish{
name:string
}
interface Water{
name:string
}
interface Bird{
name:string
}
interface Sky{
name:string
}
type Condition<T> = T extends Fish?Water:Sky;
let con:Condition<Fish> = {name:'水'};
条件类型的分发
interface Fish{
name:string
}
interface Water{
name1:string
}
interface Bird{
name:string
}
interface Sky{
name2:string
}
type Condition<T> = T extends Fish?Water:Sky;
let con1:Condition<Fish|Water> = {name1:'水'};
let con2:Condition<Fish|Water> = {name2:'水'};
内置条件类型
- TS 在内置了一些常用的条件类型,可以在 lib.es5.d.ts 中查看:
Exclude<T, U>
Extract<T, U>
NonNullable<T>
ReturnType<T>
InstanceType<T>
Exclude
type E = Exclude<string|number,string>;
let e:E = 10;
Extract
type E = Extract<string|number,string>;
let e:E = '1';
NonNullable
type E = NonNullable<string|number|null|undefined>;
let e:E = null;
ReturnType
function getUserInfo() {
return { name: "zhufeng", age: 10 };
}
type UserInfo = ReturnType<typeof getUserInfo>;
const userA: UserInfo = {
name: "zhufeng",
age: 10
};
InstanceType
class Person{
name:string;
constructor(name){
this.name = name;
}
getName(){console.log(this.name)}
}
type P = InstanceType<typeof Person>;
let p:P = {name:'zhufeng',getName(){}};