天天看點

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

繼續閱讀