TypeScript內(nèi)置工具類(lèi)型快速入門(mén)運(yùn)用
前言
TS為了方便開(kāi)發(fā)者使用,在內(nèi)部提供了非常多的工具類(lèi)型,如Partial、Required、ReadOnly等等,本篇文章主要用于記錄了一些常用的內(nèi)置工具類(lèi)型的使用及源碼實(shí)現(xiàn),以便參考。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、什么是ts內(nèi)置工具類(lèi)型
TypeScript 附帶了大量類(lèi)型,可以幫助進(jìn)行一些常見(jiàn)的類(lèi)型操作,通常稱(chēng)為 Utility Types。
二、使用示例
1.Partial
將必填參數(shù)變?yōu)榭蛇x參數(shù)
namespace a {
// 示例一:
interface A {
name: string,
age: number,
sex: string
}
// 接口A中的參數(shù)通過(guò)內(nèi)置工具類(lèi)型Partial變成了可選參數(shù)
type PartialA = Partial<A>;
let a: PartialA = {
// 此處傳參可以任意個(gè)數(shù),但只能傳已定義的參數(shù)
name: '張三',
age: 10
}
// 示例二:
interface Company {
id: number,
name: string
}
interface Person {
id: number,
name: string,
company: Company
}
// 實(shí)現(xiàn)DeepPartial,將參數(shù)深度轉(zhuǎn)換成可選參數(shù)
type DeepPartial<T> = {
[U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U];
}
type PartialPerson = DeepPartial<Person>;
let p: PartialPerson = {
// 此處的參數(shù)已經(jīng)變?yōu)榭蛇x參數(shù),可根據(jù)自己需要傳遞
id: 10,
name: '張三',
company: {
name: '美團(tuán)'
}
}
}
Partial的實(shí)現(xiàn)源碼
namespace b {
interface A {
name: string,
age: number,
sex: string
}
type Partial<T> = {
// 原理:
// 1.通過(guò)keyof拿到T中的所有key
// 2.迭代所有的key
// 3.統(tǒng)一加上可選參數(shù)處理
// 4.返回迭代值的類(lèi)型
[P in keyof T]?: T[P];
}
// 測(cè)試:
type PartialA = Partial<A>;
let a: PartialA = {
name: '張三',
age: 10
}
}
2.Required
將所有參數(shù)變?yōu)楸靥?/p>
namespace b {
interface Person {
name: string,
age?: number
}
// Required將可選參數(shù)變?yōu)楸靥?
type RequiredPerson = Required<Person>;
let person: RequiredPerson = {
name: '張三',
age: 10
}
}
Required 的實(shí)現(xiàn)源碼
namespace c {
interface Person {
name: string,
age?: number
}
type Required<T> = {
// 原理:
// 1.通過(guò)keyof拿到T中所有的key
// 2.迭代所有的key
// 3.將可選的參數(shù)變?yōu)楸靥畹膮?shù)
// 4.返回迭代屬性及類(lèi)型
// +?或者?: 代表的是可選,-?: 代表的是不可選
[P in keyof T]-?: T[P];
};
// 測(cè)試
type RequiredPerson = Required<Person>;
let person: RequiredPerson = {
name: '李四',
age: 18
}
}
3.ReadOnly
將所有參數(shù)變?yōu)橹蛔x
namespace d {
interface Person {
name: string,
age?: number
}
type ReadonlyPerson = Readonly<Person>;
let person: ReadonlyPerson = {
name: '張三',
age: 10
}
// 已經(jīng)變?yōu)橹蛔x屬性,因此此處賦值會(huì)報(bào)錯(cuò)
// person.name = '李四'; // 無(wú)法分配到 "name" ,因?yàn)樗侵蛔x屬性。ts(2540)
// person.age = 20; // 無(wú)法分配到 "age" ,因?yàn)樗侵蛔x屬性。ts(2540)
}
Readonly 的實(shí)現(xiàn)源碼
namespace e {
interface Person {
name: string,
age?: number
}
type Readonly<T> = {
// 原理:
// 1.通過(guò)keyof拿到T中所有key
// 2.迭代拿到的所有key
// 3.通過(guò)readonly關(guān)鍵字將所有屬性變?yōu)橹蛔x屬性
// 4.返回迭代屬性及類(lèi)型
readonly [P in keyof T]: T[P]
}
// 測(cè)試
type ReadonlyPerson = Readonly<Person>;
let person: ReadonlyPerson = {
name: '張三',
age: 10
}
// person.name = '李四'; // 無(wú)法分配到 "name" ,因?yàn)樗侵蛔x屬性。ts(2540)
// person.age = 20; // 無(wú)法分配到 "age" ,因?yàn)樗侵蛔x屬性。ts(2540)
}
4.Pick
撿取符合條件的屬性
namespace g {
interface Person {
name: string,
age: number,
sex: string
}
// 參數(shù)一是一個(gè)對(duì)象,參數(shù)二是要篩選的屬性
type PickPerson = Pick<Person, 'name' | 'sex'>;
let person: PickPerson = {
name: '張三',
// 由于通過(guò)Pick只撿取了name和sex屬性,因此此時(shí)給sex賦值會(huì)報(bào)錯(cuò)
// 不能將類(lèi)型“{ name: string; age: number; sex: string; }”分配給類(lèi)型“PickPerson”。
// 對(duì)象文字可以只指定已知屬性,并且“age”不在類(lèi)型“PickPerson”中。ts(2322)
// age: 10,
sex: '男'
}
}
Pick 的實(shí)現(xiàn)源碼
namespace h {
interface Person {
name: string,
age: number,
sex: string
}
// 原理:
// 1.T表示傳入的類(lèi)型定義。此處指Person接口。
// 2.K表示T的子類(lèi)型,是一個(gè)聯(lián)合類(lèi)型。此處指'name' | 'age' | 'sex'的子類(lèi)型
// 3.通過(guò)keyof拿到T中的所有key
// 3.迭代K,拿到所有傳遞進(jìn)來(lái)的子類(lèi)型
// 4.返回迭代屬性及類(lèi)型
// 簡(jiǎn)單理解:就是從一個(gè)對(duì)象中,提取一部分屬性組成新的對(duì)象
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
// 測(cè)試
type PickPerson = Pick<Person, 'name' | 'age'>
let person: PickPerson = {
name: '張三',
age: 10
}
}
5.Record
記錄類(lèi)型:將一個(gè)類(lèi)型的所有屬性值都映射到另一個(gè)屬性上并創(chuàng)建新的類(lèi)型
namespace i {
// 1.此處的K主要用來(lái)修飾obj對(duì)象的key,為string或者number
// 2.此處的T用來(lái)修飾老的類(lèi)型
// 3.此處的U用來(lái)修飾新的類(lèi)型
function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) {
// 聲明一個(gè)變量
let result: Record<K, U> = <Record<K, U>>{};
// 遍歷傳入的對(duì)象
for (const key in obj) {
// 通過(guò)callback函數(shù)處理result的屬性值
result[key] = callable(obj[key]);
}
// 返回result
return result;
}
let obj = { num1: 1, num2: 2 };
let callable = (x: number): string => x * 2 + '';
let newObj = mapObj<string | number, number, string>(obj, callable);
console.log(newObj); // { num1: '2', num2: '4' }
}
Record 的實(shí)現(xiàn)源碼
namespace j {
type Record<K extends keyof any, T> = {
// 原理:
// 1.通過(guò)keyof拿到所有的K,是一個(gè)聯(lián)合類(lèi)型。string | number | symbol
// 2.迭代K,拿到所有的屬性
// 3.返回迭代的屬性及類(lèi)型
// 注意:此處不能寫(xiě)成 type Record<K, T> = {}; any代表所有key的聯(lián)合類(lèi)型。
// 否則會(huì)報(bào)錯(cuò):不能將類(lèi)型“K”分配給類(lèi)型“string | number | symbol”。ts(2322)
[P in K]: T;
};
// 測(cè)試
function mapObj<K extends string | number, T, U>(obj: Record<K, T>, callable: (x: T) => U) {
// 聲明一個(gè)變量
let result: Record<K, U> = <Record<K, U>>{};
// 遍歷傳入的對(duì)象
for (const key in obj) {
// 通過(guò)callback函數(shù)處理result的屬性值
result[key] = callable(obj[key]);
}
// 返回result
return result;
}
let obj = { num1: 1, num2: 2 };
let callable = (x: number): string => x * 2 + '';
let newObj = mapObj<string | number, number, string>(obj, callable);
console.log(newObj); // { num1: '2', num2: '4' }
}
總結(jié)
本篇文章只記錄了這幾種內(nèi)置工具類(lèi)型,更多內(nèi)置類(lèi)型可前往https://www.typescriptlang.org/docs/handbook/utility-types.html查看。下次再見(jiàn)
到此這篇關(guān)于TypeScript內(nèi)置工具類(lèi)型快速入門(mén)運(yùn)用的文章就介紹到這了,更多相關(guān)TypeScript內(nèi)置工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
webpack與SPA實(shí)踐之管理CSS等資源的方法
本篇文章主要介紹了webpack與SPA實(shí)踐之管理CSS等資源的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Javascript實(shí)現(xiàn)關(guān)閉廣告效果
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)關(guān)閉廣告效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01
Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼
本篇文章主要是對(duì)Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02
JavaScript實(shí)現(xiàn)的微信二維碼圖片生成器的示例
二維碼分享功能大多是由后端實(shí)現(xiàn)的,對(duì)服務(wù)器的負(fù)載較重,這里有一個(gè)前端實(shí)現(xiàn)的版本,本文介紹了JavaScript實(shí)現(xiàn)的微信二維碼圖片生成器的示例,有需要的可以了解一下。2016-10-10
CSS(js)限制頁(yè)面顯示的文本字符長(zhǎng)度
限制頁(yè)面顯示的字符長(zhǎng)度,一直被眾多網(wǎng)友傾睬,本人也是一fans利用閑暇時(shí)間搜集整理了一些實(shí)用技巧,需要了解的朋友可以參考下2012-12-12
JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)播放器
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Javascript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07

