03|typescript高级用法
2020-05-17 本文已影响0人
雪燃归来
一、交叉类型
交叉类型取所有类型的并集
interface DogInterface{
run(): void
}
interface CatInterface{
jump(): void
}
let pet: DogInterface & CatInterface = {
run(){},
jump(){}
}
二、联合类型
声明的类型不确定,是多个类型中的一个
联合类型取所有类型的交集
let a: number | string = 'a'
let b: 'a' | 'b' | 'c'
let c: 1 | 2 | 3
interface DogInterface{
run(): void
}
interface CatInterface{
jump(): void
}
class Dog implements DogInterface{
run(){}
eat(){}
}
class Cat implements CatInterface{
jump(){}
eat(){}
}
enum Master { Boy, Gril}
function getPet(master: Master){
let pet = master === Master.Boy ? new Dog() : new Cat()
pet.eat() // ok
// pet.run() not assignable
// pet.jump() not assignable
}
三、可区分的联合类型
核心为:利用两种不同的类型公共属性创建不同的类型保护区块
interface Square{
kind: 'square',
size: number
}
interface Rectangle{
kind: 'rectangle',
width: number,
height: number
}
type Shape = Square | Rectangle
function area(s: Shape){
switch(s.kind){
case 'square':
return s.size * s.size
case 'rectangle':
return s.width * s.height
}
}
扩展1
interface Square{
kind: 'square',
size: number
}
interface Rectangle{
kind: 'rectangle',
width: number,
height: number
}
interface Circle{
kind: 'circle',
r: number
}
type Shape = Square | Rectangle
function area(s: Shape):number{
switch(s.kind){
case 'square':
return s.size * s.size
case 'rectangle':
return s.width * s.height
}
}
console.log(area({kind: 'circle', r: 1}))
扩展2
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
case 'rectangle':
return s.width * s.height
case 'circle':
return Math.PI * s.r ** 2
default:
return ((e: never) => {throw new Error(e)})(s)
}
}
console.log(area({kind: 'circle', r: 1}))
四、索引类型
let obj = {
a: 1,
b: 2,
c: 3
}
function getValues(obj:any,keys: string[]){
return keys.map(key => obj[key])
}
console.log(getValues(obj,['a', 'b'])) //[1, 2]
console.log(getValues(obj,['e','f'])) // [undefined, undefined]
// keyof
interface Obj{
a: number,
b: string
}
let key: keyof Obj // 'a' | 'b'
// T[k]
let value:Obj['a'] // number
// T extends U
索引类型可以实现对对象的查询、访问,然后再配合泛型约束,就能使我们建立对象、对象属性、属性值之间的关系
let obj = {
a: 1,
b: 2,
c: 3
}
function getValues<T, K extends keyof T>(obj:T, keys: K[]): T[K][]{
return keys.map(key => obj[key])
}
console.log(getValues(obj,['a','b']))
console.log(getValues(obj,['e','f']))
五、映射类型
(一)、同态类型
interface Obj{
a: string;
b: string;
c: boolean;
}
1、只读映射
type ReadonlyObj = Readonly<Obj>
/**
* Make all properties in T readonly
*/
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
2、可选映射
type PartialObj = Partial<Obj>
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
截取映射
type PickObj = Pick<Obj, 'a'|'b'>
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
(二)、非同态类型
type RecordObj = Record<'x'|'y',Obj>
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
六、条件类型
(一)、嵌套条件类型
// T extends 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>
type T2 = TypeName<string[]>
(二)、分布式条件类型
// (A | B) extends U ? never : T
type T3 = TypeName<string | string[]> // "string"|"object"
// 类型T中过滤掉可以赋值给类型U的
type Diff<T, U> = T extends U ? never : T
type T4 = Diff<"a"|"b"|"c","a"|"e">
// Diff<"a","a"|"e"> Diff<"b,"a"|"e"> Diff<"c","a"|"e">
// never | "b" | "c"
// "b" | "c"
// 过滤掉null和undefined类型
type NotNull<T> = Diff<T, undefined | null>
type T5 = NotNull<string | number | undefined | null>
Exclude<>T, U
NotNullable<T>
Extract< T, U>
type T6 = Extract<"a"|"b"|"c","a"|"e"> // a
获取函数返回值的类型
ReturnType
type T7 = ReturnType<() => string> // "string"