typescript进阶2


typescript进阶2

联合类型

let num : string | number = 1  // num的类型可以是string , 也可以是number 
keyof
将一个属性的属性名全部提取出来当做联合类型

// 1. 定义一个接口
interface Person {
  name: string
  age: number
}

type PersonKeys = keyof Person // 等同于 type PersonKeys = 'name' | 'age'

const p1: PersonKeys = 'name' // 可以
const p2: PersonKeys = 'age' // 可以
const p3: PersonKeys = 'height' // 不能将类型“"height"”分配给“name | age”
Record<K, T>
将K中的所有属性的值转化为T类型

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

type Methods = 'POST' | 'GET' | 'DELETE'

type typeMetod = Record<Methods, any> 

// type typeMetod = {
//   POST: any;
//   GET: any;
//   DELETE: any;
// }
Partial
// Partial 可选
type Partial<T> = {
  [P in keyof T]?: T[P]
}

interface Person {
  name: string
  age: number
}

// 数据有可能是请求过来的,定义一个空对象
const person1: Person = {}

const person2: Partial<Person> = {} // 可以

const person3: Partial<Person> = { name: 'xiaodu' } // 可以

const person4: Partial<Person> = { height: 1.88 } // 报错 “height”不在类型“Partial<Person>”中

// Partial 还可用于props接收的值,使其变为可选
Required 必须的, 必须有

type Required<T> = { [P in keyof T]-?: T[P] };

interface Ren {
  name?: string,
  age?: number
}

type Rentype = Required<Ren>

// 类型 "{ name: string; }" 中缺少属性 "age",但类型 "Required<Ren>" 中需要该属性。
const niuheng : Rentype = {
  name: '牛恒'
}
Pick<T, K>

// 从T中取出一系列K的属性(两者都有的属性,从T中提取)
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};


// 例如我们现在有一个接口拥有 name age sex属性, 但我们想生成一个新属性,只支持name ,age
interface Niuheng {
  name: string,
  age: number,
  sex: string,
}
  
let person: Pick<Niuheng, 'name' | 'age'> = {
  name: '牛恒',
  age: 23,
}
Readonly 将传入的属性变为只读 (浅层的)

interface Xiaohu {
  name: string,
  age: number,
  girlFriend:{
    name: string,
    age: number
  }
}

type ReadOnlyXiaohu = Readonly<Xiaohu>

const XiaoHuA : ReadOnlyXiaohu = {
  name: 'xiaohu',
  age: 18,
  girlFriend: {
    name: 'xiaomei',
    age: 18
  }
}
// type ReadOnlyXiaohu = {
//   readonly name: string;
//   readonly age: number;
//   readonly girlFriend: {
//       name: string;
//       age: number;
//   };
// }

XiaoHuA.name = 'sss' // 无法分配到 "name" ,因为它是只读属性
XiaoHuA.age = 20     // 无法分配到 "name" ,因为它是只读属性
XiaoHuA.girlFriend.age = 20 // 不报错,因此只读是浅层的
Exclude<T,U>
// 从 T 中排除 U 类型 得到一个新类型

type Exclude<T, U> = T extends U ? never : T;

type T = Exclude<1|2|3|4|5, 3|4>  // T = 1|2|5 
Extract<T,U>

// 提取 T 和 U 都包含的部分,返回一个新类型

type Extract<T, U> = T extends U ? T : never;

type T = Extract<1|2|3|4|5, 3|4>  // T = 3|4
Omit<T,K >没有内置

// 从对象 T 中排除 key是 K的属性

// 由于TS中没有内置,需要使用Pick 和 Exclude 实现

interface Person {
  name: string,
  age: number,
  sex: string,
}


let person: Omit<Person, 'name'> = {
  age: 1,
  sex: '男'
}
NonNullable
// 排除 T 为 null 、undefined

type NonNullable<T> = T extends null | undefined ? never : T;

type T = NonNullable<string | string[] | null | undefined>; // string | string[]
ReturnType
// 获取函数 T 的返回值类型

type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any; // 暂时不懂

type T1 = ReturnType<() => string>; // string
type T2 = ReturnType<(s: string) => void>; // void
参考资料:

https://blog.csdn.net/dajuna/article/details/117958613  // csdn

https://zhuanlan.zhihu.com/p/115428938                  // 知乎

https://juejin.cn/post/6844903684422254606#heading-28   // 稀土掘金

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录