Skip to content

类型工具

typescript 中使用 extends 的多种意思

typescript
{
    //1.类型继承
    {
        //1.1 extends实现类型的继承
        {
            type XIANGJUNDASHU = { name: string }

            interface houdunren extends XIANGJUNDASHU {
                age: number
            }
            //因为 houdunren 继承了 XIANGJUNDASHU 类型,同时 hd 变量实现了houdunren类型,则具有 name 和 age 属性
            const hd: houdunren = { name: "anc", age: 19 }
        }
        //1.2范型的类型限定
        {
            //这里的 extends 关键字限定 范型参数 T 必须有 id 属性 和render 函数
            function houdunren<T extends { id: number; render(n: number): number }>(arr: T[]) {
                arr.map((a) => a.render(a.id))
            }

            houdunren([{ id: 1, render(n) { return n } }])
        }
    }
    //2.类型条件判断
    {
        //宽类型
        type XAINGJUNDASHU = { name: string, age: number }
        //窄类型
        type HOUDUNREN = { name: string }
        //用于判断左侧的窄类型是否可以被赋予给右侧的宽类型
        //也可以理解为 左侧的类型是否具有右侧类型的实现,比如说 右侧类型具有 name 和 age 属性,如果左侧类型也具有 name 和 age,则表达式结果返回真
        type HDCMS = HOUDUNREN extends XAINGJUNDASHU ? true : false

        const hd: HDCMS = false
    }
    //3.范型条件分配
    {
        //3.1当传递的范型参数是一个普通类型时
        {
            type XAINGJUNDASHU = string

            type HDCMS<T> = T extends XAINGJUNDASHU ? string : boolean
            // string 类型可以被赋予给 string 类型,所以表达式为真,三元表达式返回的结果是 string,所以当范型参数是 string 时 HDCMS 的类型是 string
            const hd: HDCMS<string> = "后盾人"
        }
        //3.2当传递的范型参数是联合类型时
        {
            type XAINGJUNDASHU = string

            type HDCMS<T> = T extends XAINGJUNDASHU ? string : boolean
            //当传递的范型参数是一个联合类型的时候,会将左侧类似依次与右侧类型进行比较,结果返回一个联合类型
            const hd: HDCMS<string | number> = "后盾人"
        }
        //3.3完全限定比较
        {
            type XAINGJUNDASHU = string | number
            //用 [] 将范型参数与 需要比较的类型包裹起来,可以起到限定左右,将 extends 左右两边的类型当作整体一起进行比较
            type HDCMS<T> = [T] extends [XAINGJUNDASHU] ? string : boolean
            //完全限定比较时就不会将左侧类型依次与右侧类型进行比较,而是只进行一次比较,所以三元表达式的返回的结果应该是一个基本类型
            const hd: HDCMS<string | number> = "后盾人"
        }
    }
}

keyof 在 typescript 中的使用

typescript
{
    //例子1
    {
        //获取类型的索引签名作为联合类型
        type HOUDUNREN = keyof { name: string, age: number }
				//这里	HOUDUNREN 的类型是 name | age 属于值联合类型
        let xj: HOUDUNREN = "name"
    }
    //例子2
    {
        function getAttribute<T, D extends keyof T>(obj: T, key: D): T[D] {
            return obj[key]
        }
        //字符串也是一个对象
        getAttribute("abc", "match");
    }
}

typeof 在 typescript 中的使用

typescript
{
    //例子1
    {
        let hd = "后盾人"
        //获取变量的类型,typeof 是从变量中获取类型,所以typeof后面紧接的是变量
        type HOUDUNREN = typeof hd

        let xj: HOUDUNREN = "aaaaa"
    }
    //例子2
    {
        let hd = { name: "你好", age: 21 }

        type HOUDUNREN = typeof hd

        let xj: HOUDUNREN = { age: 11, name: "hello" }
    }
    //例子3
    {
        function getAttribute<T>(obj: T, key: string) {
            return obj[key as keyof typeof obj]
        }
        //字符串也是一个对象
        getAttribute("abc", "match");
    }
}

typescript 中类型工具 Exclude 的使用

typescript
{
    // type EXCLUDE<T,U> = T extends U ? never : T

    type XIANGJUNDASHU = string | boolean

    type HOUDUNREN = string | number | boolean

    const hd: Exclude<HOUDUNREN, XIANGJUNDASHU> = 100
}

typescript 中类型工具 Extract 的使用

typescript
{
    // type EXCLUDE<T,U> = T extends U ? never : T

    type XIANGJUNDASHU = string | boolean

    type HOUDUNREN = string | number | boolean
    //Extract 与 Exclude 使用正好相反,保留右边的类型
    const hd: Extract<HOUDUNREN, string | boolean> = "hello"
}

typescript中 类型工具 Pick 的使用

typescript
{
    //模拟 pick 类型工具的实现
    {
        type HOUDUNREN = { name: string, age: number, skill: string }

        type PICK<T, U extends keyof T> = {
            [k in U]: T[k]
        }
        type HD = PICK<HOUDUNREN, "name" | "age">
    }
    //使用 Pick 类型工具
    {
        type HOUDUNREN = { name: string, age: number, skill: string }

        type HD = Pick<HOUDUNREN, "name" | "age">
    }
}

Partial 类型工具的使用,将属性类型转为可选

typescript
{
    //模拟 Partial 类型工具的实现
    {
        type XAINGJUNDASHU = { name: string, age: number }

        type PARTIAL<T> = {
            [k in keyof T]?: T[k]
        }
        const hd: PARTIAL<XAINGJUNDASHU> = { name: "xj" }
    }
    //使用 Partial 类型工具
    {
        type XAINGJUNDASHU = { name: string, age: number }

        const hd: Partial<XAINGJUNDASHU> = { name: "xj" }
    }
}

typescript 中的索引签名

typescript
{
    {
        type HOUDUNREN = {
            [key: `${string}Hd`]: string
            // name:string,
            city: string
        }
        let xj: HOUDUNREN = {
            nameHd: "xaxa",
            city: "xsacfc"
        }
    }
    //使用typescript 的类型工具 定义类型的索引签名
    {
        type HOUDUNREN = Record<"name" | "age", string | number>

        let xj: HOUDUNREN = { age: 15, name: "你好" }
    }
}

交叉类型在 typescript 中的使用

typescript
{
    interface A { name: string }

    type B = { age: number }

    let c: A & B = { age: 15, name: "xsax" }
}

infer 类型工具的使用

typescript
{
    //例子1
    {
        type HD = { name: string, age: number }

        type AttrType<T> = T extends { name: infer M, age: infer M } ? M : T;

        type valueType = AttrType<HD>
    }
    //例子2
    {
        type HD = (n:string) => number[]

        type GetFunctionReturenValue<T> = T extends ((...args:any) =>(infer M)[]) ? M : T 

        type valueType = GetFunctionReturenValue<HD>
    }
}

typescript 索引 as 类型断言

typescript
{
    //根据索引签名过滤属性
    {
        type User = { name: string, age: number, get(): void }

        //当索引签名的类型是never时,此索引签名会被过滤掉
        type FilterObjectProperty<T, U> = {
            [K in keyof T as Exclude<K, U>]: T[K]
        }

        type HD = FilterObjectProperty<User, "name" | "age">
    }
    //根据值类型进行过滤
    {
        type User = { name: string, age: number, get(): void }

        type FilterObjectProperty<T, U> = {
            [K in keyof T]: T[K] extends U ? never : K
        }[keyof T]

        type HD = Pick<User, FilterObjectProperty<User, Function | number>>
    }
}