91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TypeScript高級類型有哪些及怎么用

發布時間:2022-04-19 16:20:30 來源:億速云 閱讀:121 作者:iii 欄目:移動開發

本篇內容主要講解“TypeScript高級類型有哪些及怎么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“TypeScript高級類型有哪些及怎么用”吧!

前言

對于有 javascript 基礎的同學來說,入門 typescript 其實很容易,只需要簡單掌握其基礎的類型系統就可以逐步將 js 應用過渡到 ts 應用。

// js
const double = (num) => 2 * num

// ts
const double = (num: number): number => 2 * num

然而,當應用越來越復雜,我們很容易把一些變量設置為 any 類型,typescript 寫著寫著也就成了 anyscript。

在講解高級類型之前,我們需要先簡單理解泛型是什么。

泛型是強類型語言中比較重要的一個概念,合理的使用泛型可以提升代碼的可復用性,讓系統更加靈活。下面是維基百科對泛型的描述:

泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數指明這些類型。

泛型通過一對尖括號來表示( <> ),尖括號內的字符被稱為 類型變量 ,這個變量用來表示類型。

function copy<t>(arg: t): t {
 if (typeof arg === 'object') {
 return json.parse(
  json.stringify(arg)
 )
 } else {
 return arg
 }
}

這個類型 t,在沒有調用 copy 函數的時候并不確定,只有調用 copy 的時候,我們才知道 t 具體代表什么類型。

const str = copy<string>('my name is typescript')

TypeScript高級類型有哪些及怎么用

我們在 vs code 中可以看到 copy 函數的參數以及返回值已經有了類型,也就是說我們調用 copy 函數的時候,給類型變量 t 賦值了 string。其實,我們在調用 copy 的時候可以省略尖括號,通過 ts 的類型推導是可以確定 t 為 string 的。

TypeScript高級類型有哪些及怎么用

高級類型

除了 string、number、boolean 這種基礎類型外,我們還應該了解一些類型聲明中的一些高級用法。

交叉類型(&)

交叉類型說簡單點就是將多個類型合并成一個類型,個人感覺叫做「合并類型」更合理一點,其語法規則和邏輯 “與” 的符號一致。

t & u

假如,我現在有兩個類,一個按鈕,一個超鏈接,現在我需要一個帶有超鏈接的按鈕,就可以使用交叉類型來實現。

interface button {
 type: string
 text: string
}

interface link {
 alt: string
 href: string
}

const linkbtn: button & link = {
 type: 'danger',
 text: '跳轉到百度',
 alt: '跳轉到百度',
 href: 'http://www.baidu.com'
}

聯合類型(|)

聯合類型的語法規則和邏輯 “或” 的符號一致,表示其類型為連接的多個類型中的任意一個。

t | u

例如,之前的 button 組件,我們的 type 屬性只能指定固定的幾種字符串。

interface button {
 type: 'default' | 'primary' | 'danger'
 text: string
}

const btn: button = {
 type: 'primary',
 text: '按鈕'
}

類型別名(type)

前面提到的交叉類型與聯合類型如果有多個地方需要使用,就需要通過類型別名的方式,給這兩種類型聲明一個別名。類型別名與聲明變量的語法類似,只需要把 const 、 let 換成 type 關鍵字即可。

type alias = t | u

type innertype = 'default' | 'primary' | 'danger'

interface button {
 type: innertype
 text: string
}

interface alert {
 type: buttontype
 text: string
}

類型索引(keyof)

keyof 類似于 object.keys ,用于獲取一個接口中 key 的聯合類型。

interface button {
 type: string
 text: string
}

type buttonkeys = keyof button
// 等效于
type buttonkeys = "type" | "text"

還是拿之前的 button 類來舉例,button 的 type 類型來自于另一個類 buttontypes,按照之前的寫法,每次 buttontypes 更新都需要修改 button 類,如果我們使用 keyof 就不會有這個煩惱。

interface buttonstyle {
 color: string
 background: string
}
interface buttontypes {
 default: buttonstyle
 primary: buttonstyle
 danger: buttonstyle
}
interface button {
 type: 'default' | 'primary' | 'danger'
 text: string
}

// 使用 keyof 后,buttontypes修改后,type 類型會自動修改 
interface button {
 type: keyof buttontypes
 text: string
}

類型約束(extends)

這里的 extends 關鍵詞不同于在 class 后使用 extends 的繼承作用,泛型內使用的主要作用是對泛型加以約束。我們用我們前面寫過的 copy 方法再舉個例子:

type basetype = string | number | boolean

// 這里表示 copy 的參數
// 只能是字符串、數字、布爾這幾種基礎類型
function copy<t extends basetype>(arg: t): t {
 return arg
}

TypeScript高級類型有哪些及怎么用

如果我們傳入一個對象就會有問題。

TypeScript高級類型有哪些及怎么用

extends 經常與 keyof 一起使用,例如我們有一個方法專門用來獲取對象的值,但是這個對象并不確定,我們就可以使用 extends 和 keyof 進行約束。

function getvalue<t, k extends keyof t>(obj: t, key: k) {
 return obj[key]
}

const obj = { a: 1 }
const a = getvalue(obj, 'a')

TypeScript高級類型有哪些及怎么用

這里的 getvalue 方法就能根據傳入的參數 obj 來約束 key 的值。

類型映射(in)

in 關鍵詞的作用主要是做類型的映射,遍歷已有接口的 key 或者是遍歷聯合類型。下面使用內置的泛型接口 readonly 來舉例。

type readonly<t> = {
 readonly [p in keyof t]: t[p];
};

interface obj {
 a: string
 b: string
}

type readonlyobj = readonly<obj>

TypeScript高級類型有哪些及怎么用

我們可以結構下這個邏輯,首先 keyof obj 得到一個聯合類型 'a' | 'b' 。

interface obj {
 a: string
 b: string
}

type objkeys = 'a' | 'b'

type readonlyobj = {
 readonly [p in objkeys]: obj[p];
}

然后 p in objkeys 相當于執行了一次 foreach 的邏輯,遍歷 'a' | 'b'

type readonlyobj = {
 readonly a: obj['a'];
 readonly b: obj['b'];
}

最后就可以得到一個新的接口。

interface readonlyobj {
 readonly a: string;
 readonly b: string;
}

條件類型(u ? x : y)

條件類型的語法規則和三元表達式一致,經常用于一些類型不確定的情況。

t extends u ? x : y

上面的意思就是,如果 t 是 u 的子集,就是類型 x,否則為類型 y。下面使用內置的泛型接口 extract 來舉例。

type extract<t, u> = t extends u ? t : never;

如果 t 中的類型在 u 存在,則返回,否則拋棄。假設我們兩個類,有三個公共的屬性,可以通過 extract 提取這三個公共屬性。

interface worker {
 name: string
 age: number
 email: string
 salary: number
}

interface student {
 name: string
 age: number
 email: string
 grade: number
}


type commonkeys = extract<keyof worker, keyof student>
// 'name' | 'age' | 'email'

TypeScript高級類型有哪些及怎么用

工具泛型

typesscript 中內置了很多工具泛型,前面介紹過 readonly 、 extract 這兩種,內置的泛型在 typescript 內置的 lib.es5.d.ts 中都有定義,所以不需要任何依賴都是可以直接使用的。下面看看一些經常使用的工具泛型吧。

TypeScript高級類型有哪些及怎么用

partial

type partial<t> = {
 [p in keyof t]?: t[p]
}

partial 用于將一個接口的所有屬性設置為可選狀態,首先通過 keyof t ,取出類型變量 t 的所有屬性,然后通過 in 進行遍歷,最后在屬性后加上一個 ? 。

我們通過 typescript 寫 react 的組件的時候,如果組件的屬性都有默認值的存在,我們就可以通過 partial 將屬性值都變成可選值。

import react from 'react'

interface buttonprops {
 type: 'button' | 'submit' | 'reset'
 text: string
 disabled: boolean
 onclick: () => void
}

// 將按鈕組件的 props 的屬性都改為可選
const render = (props: partial<buttonprops> = {}) => {
 const baseprops = {
 disabled: false,
 type: 'button',
 text: 'hello world',
 onclick: () => {},
 }
 const options = { ...baseprops, ...props }
 return (
 <button
  type={options.type}
  disabled={options.disabled}
  onclick={options.onclick}>
  {options.text}
 </button>
 )
}

required

type required<t> = {
 [p in keyof t]-?: t[p]
}

required 的作用剛好與 partial 相反,就是將接口中所有可選的屬性改為必須的,區別就是把 partial 里面的 ? 替換成了 -? 。

record

type record<k extends keyof any, t> = {
 [p in k]: t
}

record 接受兩個類型變量, record 生成的類型具有類型 k 中存在的屬性,值為類型 t。這里有一個比較疑惑的點就是給類型 k 加一個類型約束, extends keyof any ,我們可以先看看 keyof any 是個什么東西。

TypeScript高級類型有哪些及怎么用

大致一直就是類型 k 被約束在 string | number | symbol 中,剛好就是對象的索引的類型,也就是類型 k 只能指定為這幾種類型。

我們在業務代碼中經常會構造某個對象的數組,但是數組不方便索引,所以我們有時候會把對象的某個字段拿出來作為索引,然后構造一個新的對象。假設有個商品列表的數組,要在商品列表中找到商品名為 「每日堅果」的商品,我們一般通過遍歷數組的方式來查找,比較繁瑣,為了方便,我們就會把這個數組改寫成對象。

interface goods {
 id: string
 name: string
 price: string
 image: string
}

const goodsmap: record<string, goods> = {}
const goodslist: goods[] = await fetch('server.com/goods/list')

goodslist.foreach(goods => {
 goodsmap[goods.name] = goods
})

pick

type pick<t, k extends keyof t> = {
 [p in k]: t[p]
}

pick 主要用于提取接口的某幾個屬性。做過 todo 工具的同學都知道,todo工具只有編輯的時候才會填寫描述信息,預覽的時候只有標題和完成狀態,所以我們可以通過 pick 工具,提取 todo 接口的兩個屬性,生成一個新的類型 todopreview。

interface todo {
 title: string
 completed: boolean
 description: string
}

type todopreview = pick<todo, "title" | "completed">

const todo: todopreview = {
 title: 'clean room',
 completed: false
}

TypeScript高級類型有哪些及怎么用

exclude

type exclude<t, u> = t extends u ? never : t

exclude 的作用與之前介紹過的 extract 剛好相反,如果 t 中的類型在 u 不存在,則返回,否則拋棄。現在我們拿之前的兩個類舉例,看看 exclude 的返回結果。

interface worker {
 name: string
 age: number
 email: string
 salary: number
}

interface student {
 name: string
 age: number
 email: string
 grade: number
}


type excludekeys = exclude<keyof worker, keyof student>
// 'name' | 'age' | 'email'

TypeScript高級類型有哪些及怎么用

取出的是 worker 在 student 中不存在的 salary 。

omit

type omit<t, k extends keyof any> = pick<
 t, exclude<keyof t, k>
>

omit 的作用剛好和 pick 相反,先通過 exclude<keyof t, k> 先取出類型 t 中存在,但是 k 不存在的屬性,然后再由這些屬性構造一個新的類型。還是通過前面的 todo 案例來說,todopreview 類型只需要排除接口的 description 屬性即可,寫法上比之前 pick 精簡了一些。

interface todo {
 title: string
 completed: boolean
 description: string
}

type todopreview = omit<todo, "description">

const todo: todopreview = {
 title: 'clean room',
 completed: false
}

TypeScript高級類型有哪些及怎么用

到此,相信大家對“TypeScript高級類型有哪些及怎么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新蔡县| 瑞丽市| 江安县| 界首市| 阿拉善左旗| 图们市| 南郑县| 泗水县| 根河市| 伊吾县| 百色市| 荣成市| 本溪| 东莞市| 东山县| 甘泉县| 阿克| 永康市| 平南县| 福贡县| 周至县| 大城县| 固安县| 石台县| 当涂县| 洞头县| 休宁县| 土默特右旗| 恩施市| 青阳县| 曲沃县| 石家庄市| 海淀区| 沈阳市| 库尔勒市| 乌恰县| 宜宾县| 孟州市| 如皋市| 昭通市| 武川县|