天天看点

06 ts扩展知识ts模块化命名空间类型声明tsconfig.json文件条件类型(了解)条件类型-类型推断infer分发条件类型内置工具-类型体操

目录

ts模块化

命名空间

类型声明

tsconfig.json文件

条件类型(了解)

条件类型-类型推断infer

分发条件类型

内置工具-类型体操

Partial

Required

Readonly

Record

pick

omit

其他

ts模块化

 ts从2012年开始跟进模块化,ts支持多种模块化方案

2015年esmodule发布,所以在ts中最主要使用的模块化方案就是es module

用法与在js中使用无异,这里说明一些特殊用法

 内置类型导入

// 导入其他函数与js的esmodule一样
import {sum} from './utils/Math'
// 在导入类型时,最好加上type
import {type IPerson,type IKun} from './utils/type'
// 加上type优点: 在babel等进行打包编译时可以去掉
// 其他写法: 当导入的全是type时,type可以写在外边
// import type {IPerson, IKun} from './utils/type'
console.log(sum(10,20));
const obj: IPerson = {
    name: 'zhao',
    age: 12
}
           

命名空间

ts在ES module前推出的模块化方案,现已经不推荐使用

// 命名空间,不同命名空间变量名可重复
namespace price {
    function format() {}
    const name = 'xx'
}
// 导出
export namespace data {
    // 这个也需要导出
    export function format() {}
    // 没导出只能自己内部使用
    const name = 'zz'
}
           

类型声明

在我们开发中所用的类型,有些是我们自己写的,但也用到了一些别的内容(HTMLDivElement)

这些类型来自哪里?这与ts类型的管理与查找规则有关

.d.ts文件

类型声明文件 .d.ts文件 用来做类型声明, 不能在里面写逻辑代码,

仅仅用来做类型检测,告诉ts我们有哪些类型

类型分明大致分为三种:

    1,内置类型声明(HTMLImageElement,Promise等)

    2,外部定义类型声明(我们引入的第三方库,例如axios)

    3,自己定义类型声明

tsconfig.json文件

作用一:  让TypeScript Compiler在编译时,知道如何去编译ts和进行类型检测

    比如: 将ts代码编译成什么版本的javascript代码,

作用二:  让编译器(vscode)可以按照正确的方式识别ts代码

    比如:  对那些语法进行提示,类型错误检测等等

tsconfig.json在编译时如何被使用?

在调用tsc时,指定文件,tsc index.ts 会将改文件编译成js文件

只使用tsc命令,找到包含tsconfig.json目录(根目录)编译所有ts文件

在webpack中使用ts-loader进行打包时,会自动读取tsconfig文件,根据配置编译ts代码

tsconfig.json常用选项

当我们在开发中,选择ts模板时,会自动配好,一般不需要我们修改

条件类型(了解)

type myType = number | string

// 语法: type1 extends type2 ? trueType : falseType
// 类似于js中的三元运算符 如果type1继承type2则返回trueType,否则返回falseType
// 只有extends这一种判断

//应用

// function sum(num1: number,num2: number): number
// function sum(num1: string,num2: string): string
function sum<T extends myType>(num1: T,num2: T): T extends number ? number : string
function sum(num1: any, num2: any) {
    console.log(num1+num2);
    return num1+num2
}
sum('str','xxx')
sum(1,2)

export {}
           

条件类型-类型推断infer

// 条件类型提供了infer关键词,可以从正在比较的类型中推断类型,然后再true分支中引用

// 应用: 假如我们现在有一个函数类型,获取他的参数类型与返回值类型
// ts有内置工具ReturnType
type fnType = ()=>void
type fnType2 = (num1: number,num2: number)=>number
type fnType3 = (num1: string,num2: string)=>string

type resType = ReturnType<fnType>
// 获取返回值类型
type myReturnType<T extends (...args: any[])=>any> = T extends (...args: any[])=> infer R ? R : never
// 获取参数类型
type myParamsType<T extends (...args: any[])=>any> = T extends (...args: infer P)=> any ? P : never

// 测试
type resType2 = myReturnType<fnType2>
type resType3 = myReturnType<fnType3>

type resType4 = myParamsType<fnType2>
type resType5 = myParamsType<fnType3>
           

分发条件类型

// 当我们在泛型中使用条件类型,如果传入一个联合类型,就会变成分发的

// 应用: toArray
type toArray<T> = T[]

type numArr = toArray<number>
type numStrArr = toArray<number | string> // (number | string)[] 想要的是 number[] | string[]
// 分发条件类型
type toArray2<T> = T extends any ? T[] : never
type numStrArr2 = toArray2<number | string> //  number[] | string[]
           

内置工具-类型体操

Partial

// 将一个对象类型的所有参数变成可选的
interface IKun {
    name: string,
    age: number,
    slogan: string
}

type newIKun = Partial<IKun>
// 实现
type MyPartial<T> = {
  [P in keyof T]?: T[P]
}
type newIKun2 = MyPartial<IKun>
           

Required

// 将一个对象类型的所有参数变成必选的
interface IKun {
    name: string,
    age: number,
    slogan?: string
}

type newIKun = Required<IKun>
// 实现
type MyRequired<T> = {
  [P in keyof T]-?: T[P]
}
type newIKun2 = MyRequired<IKun>
export {}
           

Readonly

// 将一个对象类型的所有参数变成必选的
interface IKun {
    name: string,
    age: number,
    slogan?: string
}

type newIKun = Readonly<IKun>
// 实现
type MyReadonly<T> = {
  readonly [P in keyof T]: T[P]
}
type newIKun2 = MyReadonly<IKun>
export {}
           

Record

// record: 接受两个参数,返回一个对象类型
//第一个参数是一个联合类型,每一项作为key
// 第二个参数作为value
interface IKun {
    name: string,
    age: number,
    slogan?: string
}
type keys = '上海' | '北京'
type newIKun = Record<keys,IKun>
const IKun1: newIKun = {
    '上海' : {
        name: 'xxx',
        age: 10
    },
    '北京' :{
        name: 'yyy',
        age: 5
    }
}
// 实现
// K必须是联合类型,keyof any返回 number | string | symbol
type MyRecord<K extends keyof any,T> = {
    [P in K]: T
}
type newIKun2 = MyRecord<keys,IKun>
export {}
           

pick

// pick: 接受两个参数,
// 第一个参赛: 一个对象类型
// 第二个参数: 第一个参数key的联合类型的子集
// 返回: 一个对象类型,所有的key是第二个参数选项

interface IKun {
    name: string,
    age: number,
    slogan?: string
}

type newIKun = Pick<IKun,'name'| 'slogan'>
// 结果
// type newIKun = {
//     name: string;
//     slogan?: string | undefined;
// }
// 实现

type MyPick<T,K extends keyof T> = {
    [P in K]: T[P]
}
type newIKun2 = MyPick<IKun,'name'| 'slogan'>
export {}
           

omit

// omit: 作用与pick相反 接受两个参数,
// 第一个参赛: 一个对象类型
// 第二个参数: 第一个参数key的联合类型的子集
// 返回: 一个对象类型,去除第二个参数的key

interface IKun {
    name: string,
    age: number,
    slogan?: string
}

type newIKun = Omit<IKun,'name'| 'slogan'>
// 结果
// type newIKun = {
//     age: number;
// }
// 实现

type MyOmit<T,K extends keyof T> = {
    // 获取所有key,看key在不在K中,做一次判断
    [P in keyof T as P extends K ? never : P]: T[P]
}
type newIKun2 = MyOmit<IKun,'name'| 'slogan'>
export {}
           

其他

exclude<联合类型,去除的项>

extract<联合类型,只包含的项>

NonNullable<联合类型> : 去除联合类型中的null与undefined

继续阅读