Typescript

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"
上一篇 下一篇

猜你喜欢

热点阅读