小美老师,在实践中使用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大概就讲那么多。之后还会在补充。

相关推荐
无双_Joney17 分钟前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(功能篇)
前端·后端·nestjs
在云端易逍遥19 分钟前
前端必学的 CSS Grid 布局体系
前端·css
EMT19 分钟前
在 Vue 项目中使用 URL Query 保存和恢复搜索条件
javascript·vue.js
ccnocare20 分钟前
选择文件夹路径
前端
艾小码20 分钟前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
闰五月21 分钟前
JavaScript作用域与作用域链详解
前端·面试
泉城老铁25 分钟前
idea 优化卡顿
前端·后端·敏捷开发
前端康师傅25 分钟前
JavaScript 作用域常见问题及解决方案
前端·javascript
司宸26 分钟前
Prompt结构化输出:从入门到精通的系统指南
前端