小美老师,在实践中使用typescript的总结

一. 前言

在日常开发中TypeScript已经很常见啦。但是我们真的可以很熟悉的、或者说很优雅的使用ts去声明一些类型么?如果你觉得还差那么一点点味道的话,可以跟着小美老师来了解一下哦。

二. 类型总结

2.1 ts内置类型

keyof

定义:

获取类型内的所有keys,获取的是一个由当前key组成的联合类型。

使用:

js 复制代码
    type Texample = {
        x: number,
        y: string
    }
    
    type Tkey = keyof Texample;
    等同于:
    type Tkey = x | y;

注意一下: typeof any:

js 复制代码
    typeof any;
    等同于:
    type Tex = string | number | symbol

in操作符

遍历类型

遍历联合类型里面的每个key,把联合类型中每一个属性名赋值给 P

在这个例子里面: P就是属性,any就是类型。因为unions里面有三个属性,所以TExuni里面也有三个属性,类型都为any

extends

extends是 ts 里一个很常见的关键字,日常中的使用比较多

  1. 继承基本用法

A extends B (A类型继承于B类型)

js 复制代码
type Ex1 = {
    name: string,
    age: number
}

interface Ex2 extends Ex1 {}
  1. 继承的扩展
js 复制代码
    type Ex1 = {
    name: string,
    age: number
}

interface Ex2 extends Ex1 {}

// 在继承的同时,可以自己扩展属性。
export interface Ex3 extends Ex2 {
    value: string
}
  1. 类型的分配

extends还有一用途就是用来判断一个类型是不是可以分配给另一个类型

SomeType extends OtherType ? TrueType : FalseType; extends

举个例子:

js 复制代码
type Ex1 = {
    name: string
}
type Ex2 = {
    name: string
}
type Ex3 = Ex1 extends Ex2 ? 'yes' : 'no'  // type Ex3 = "yes"

注意: 这里的Ex1 extends Ex2,是指类型Ex1可以分配给类型Ex2,而不是说类型Ex1是类型Ex2的子集

js 复制代码
 type Ex1 = {
    name: string,
    age: number
}
type Ex2 = {
    name: string
}
type Ex3 = Ex1 extends Ex2 ? 'yes' : 'no'

// 这里Ex1有两个属性,Ex2有一个属性(这个属性包含在Ex1里面)Ex1可以把类型分配给Ex2

Pick<Type, Keys>

从 Type 类型中选取部分 Keys,并返回新的类型,这里 Type类型 常用于对象类型

js 复制代码
type Pick<T, K extends keyof T> = {
    [P in K]: T[p]
}

// keyof T  获取T中的所有类型
// K extends keyof T  K继承T
// P in K  遍历K中的类型
js 复制代码
    interface IEx1 {
        name: string,
        age: number,
        op: string
    }
    type TEx2 = Pick<IEx1, 'name' | 'age'>  // { name: string; age: number; }

注意: 如果想生成的类型包含自定义属性,则需要在 原类型 中添加 [key: string]: any

typescript 复制代码
    interface IEx1 {
        name: string,
        age: number,
        op: string,
        [key: string]: any

    }
    type TEx2 = Pick<IEx1, 'name' | 'age' | 'other'>  // { name: string; age: number; other: any}
    

Partial<Type>

将Type中的所有属性设置为可选

js 复制代码
    type Partial<T> = {
        [P in keyof T]?: T[P]
    }
    // 获取T下面所有属性,然后遍历设置为?
js 复制代码
    interface IPart1 {
        name: string,
        age: number,
        sex: string
    }
    
    type IPart2 = Partial<IPart1>
    等同于:
    type IPart2 = {  
        name?: string | undefined;  
        age?: number | undefined;  
        sex?: string | undefined;  
    }

Required<Type>

将Type中的所有属性设置为必须

js 复制代码
    type Required<T> = {
        [P in keyof T]-?: T[p]
    }
    // '-?:' 字符语法的作用,标记映射类型的属性为必需。它只能在映射类型中使用,在其他类型中使用会报错
js 复制代码
    interface IRequired1 {
        name: string,
        age?: number,
        job?: string
    }
    
    type Irequired2 = Required<IRequired1>
    等同于:
    type Irequired2 = {  
        name: string;  
        age: number;  
        job: string;  
    }

Readonly<Type>

将 Type 中的所有属性设为只读

bash 复制代码
    type Readonly<T> = {
        readonly [P in keyof T]: T[P]
    }
    // readonly设置为只读
js 复制代码
    interface IReadonly1 {
        name: string,
        age: number
    }
    
    type IReadonly2 = Readonly<IReadonly1>
    等同于
    type IReadonly2 = {  
        readonly name: string;  
        readonly age: number;  
    }
    

Record<Keys, Type>

将 Keys 中的所有属性值都转换为 Type 类型,并返回新的对象类型

css 复制代码
type Record<T, K> = {
    [P in keyof T]: K
}
js 复制代码
    type TRecord1 = 'options1' | 'options2';

    type KRecord = {
        name: string,
        age: string
    }

    type TRecord2 = Record<TRecord1, KRecord>;
    等同于:
    type TRecord2 = {
        options1: KRecord;
        options2: KRecord;
    }

Exclude<UnionType, ExcludedMembers>

从UnionType中剔除可以赋值给ExcludedMembers的类型

js 复制代码
    type Exclude<T, U> = T extends U ? never : T
    // T中有,U没有, 返回
    // 就相当于找补集

    
    如果T是联合类型,循环执行
    (T1 extends U ? never : T1) | ( T2 extends U ? never : T2) | ...
js 复制代码
    type TExclude1 = Exclude<"a" | "b" | "c" | "d" , "a" | "c">
    // T中有a,b,c,d。U中有a,c   => b、d
    等同于:
    type TExclude1 = "b" | "d"

Extract<Type, Union>

提取Type中可以赋值给Union的类型

js 复制代码
    type Extract<T, U> = T extends U ? T : never
    就相当于找交集
js 复制代码
    type TExtract1 = Extract<'a' | 'b' | 'c', 'a' | 'c'>
    等同于:
    type TExtract1 = "a" | "c"

NonNullable<Type>

去除 null 和 undefined 后的新类型

js 复制代码
    type NonNullable<T> = T extends null | undefined ? never : T
js 复制代码
    type TNo1 = null | number | boolean | undefined;
    type TNo2 = NonNullable<TNo1>
    等同于:
    type TNo2 = number | boolean

Omit<Type, Keys>

获取 Type 中不包含 Keys 属性的 新类型

r 复制代码
    type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
    // keyof T 获取T中的所有类型
    // Exclude<keyof T, K> Exclude T 中可以赋值的类型
    // Pick 从T中选取可赋值的类型
js 复制代码
    interface IOm1 {
    name:string,
    age?: number,
    sex: string,
  }

  type TOmit = Omit<IOm1, 'name' | 'sex' | 'op'>
  等同于
  type TOmit = {
    age?: number | undefined;
  }

ReturnType<Type>

提取函数的返回值类型

r 复制代码
    type ReturnType<T> = T extends (...args: any[]) => infer P ? P : any;
js 复制代码
    type Func = () => number;
    type Test = ReturnType<Func>; // Test = number

2.2 Vue3.0 中的内置Ts类型

ComponentInternalInstance

用于声明getCurrentInstance的类型

例如:

这里我们需要类型改成ComponentInternalInstance

js 复制代码
 import { getCurrentInstance, ComponentInternalInstance } from 'vue';
 let { appContext } = getCurrentInstance() as ComponentInternalInstance;

Ref

声明一个Ref类型的响应式数据

js 复制代码
    import { ref, Ref } from 'vue';
   
    export type componentListHooksType = {
         listCount: Ref<number>
     }

PropType

为props声明类型

js 复制代码
    import type { PropType } from 'vue'
    
    export default defineComponent({
         store: {
              required: true,
              type: Object as PropType<TableHeaderProps<DefaultRow>['store']>,
        },
    })

三. TS中的类型断言

个人觉得在Ts中类型断言是很重要的。有时候你会遇到这样的情况,你会比 TypeScript 更了解某个值的详细信息。通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。

通过类型断言这种方式可以告诉编译器,"please 相信俺!"。类型断言好比其他语言里的类型转换,但是不进行特殊的数据检查和解构。它没有运行时的影响,只是在编译阶段起作用

类型断言有两种方式:

<Type>

江湖人称尖括号写法

js 复制代码
    let name: any = 'name';
    let nameLen: number = (<string>name).length
    

as

js 复制代码
    type Td = {
        name: string,
        age: number,
        sex: string
    }

    const Tarr = [] as Td[]

类型转换

Ts中的类型有高等级和低等级之分, 拿基本类型来说:

string | number | boolean 这些是平等的,也就是说不能把一个string类型直接断言到number类型。需要进行低等级类型的转换。比如: 先转为unknown 或者 any

举个例子:

先把str降级到any或者unknown,然后进行断言处理。

OK,这期的Ts大概就讲那么多。之后还会在补充。

相关推荐
众生回避1 分钟前
鸿蒙ms参考
前端·javascript·vue.js
洛千陨1 分钟前
Vue + element-ui实现动态表单项以及动态校验规则
前端·vue.js
笃励38 分钟前
Angular面试题五
javascript·ecmascript·angular.js
GHUIJS1 小时前
【vue3】vue3.5
前端·javascript·vue.js
-seventy-1 小时前
对 JavaScript 原型的理解
javascript·原型
&白帝&1 小时前
uniapp中使用picker-view选择时间
前端·uni-app
魔术师卡颂1 小时前
如何让“学源码”变得轻松、有意义
前端·面试·源码
谢尔登1 小时前
Babel
前端·react.js·node.js
ling1s1 小时前
C#基础(13)结构体
前端·c#
卸任2 小时前
使用高阶组件封装路由拦截逻辑
前端·react.js