TS中的一些關鍵詞總結(文末送書)

TS中的一些關鍵詞總結

最近一直在寫TS,偶爾會遇到一些本身以前沒見過的一些符號或者關鍵詞,就隨手記錄下來,本篇文章就是對這段時間遇到的進行了總結。html

目錄概覽

  • TS中的一些符號git

    • ! 斷言操做符
    • ?. 鏈判斷運算符
  • TS中的一些關鍵詞github

    • type
    • interface
    • typeof
    • keyof
    • in
  • TS中的一些內置類型web

    • Partial<T> 將類型的屬性變成可選
    • Required<T>將類型的屬性變成必選
    • Pick 從某個類型中挑出一些屬性出來
    • Record
    • Mutable<T> 將類型的屬性變成可修改
    • Readonly<T> 類型的屬性變成只讀
    • ReturnType 用來獲得一個函數的返回值類型

下面的一些例子均可以在 TypeScript Playground[1] 中進行嘗試。左側是TS,右側是編譯後的JS。typescript

TS中的一些符號

! 斷言操做符

! 的做用是斷言某個變量不會是 null/undefined,告訴編輯器中止報錯。segmentfault

const obj = {
    name'牧碼的星星'
}
const a = obj!.name; // 假設 obj是你從後端獲取的獲取

肯定 obj.name 必定是存在的且不是null/undefined,使用! 只是消除編輯器報錯,不會對運行有任何影響。後端

屬性或者參數中使用 !,表示強制解析(告訴 typescript 編譯器,這裏必定有值); 變量後使用 !: 表示類型推薦排除 null/undefined。微信

?. 鏈判斷運算符

const orderId = response.result.data.orderId;

上面這種寫法,很容易出現這種問題 orderId is undefined,稍微有些經驗的咱們立馬就能想到,確定是代碼中 response.result.datanull 或者 undefined ,這樣,你確定獲取不到 orderId。因此經驗豐富的咱們在遇到獲取層級比較多的對象的時候,通常都是像下面這樣寫。app

// 正確的寫法
const orderId = (response
  && response.result
  && response.result.data
  && response.result.data.orderId) || '';

咱們可使用 ?. 來簡化上面的代碼。框架

const orderId = response?.result?.data?.orderId || '';

上面代碼使用了?.運算符,直接在鏈式調用的時候判斷,左側的對象是否爲null或undefined。若是是的,就再也不往下運算,而是返回undefined。

?. 支持以下語法

obj?.prop // 對象屬性
obj?.[expr] // 對象屬性
arr?.[index] // 獲取數據中 index 下標對應的值
func?.(...args) // 函數或對象方法的調用

?.&& 的區別

TS中的一些關鍵詞

type 類型別名用來給一個類型起個新名字

type SetUser = (name: string, age: number) => void;

類型別名經常使用於聯合類型(聯合類型表示取值能夠爲多種類型中的一種),好比常見的以下寫法

type UploadType = 'drag' | 'select';

interface

interface 和 type 的用法其實差很少,interface 也是用來定義類型的

interface SetUser = {
    (name: string, age: number) => void;
}

type和interface的區別

都支持拓展,可是語法不一樣

interface Name { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}
type Name = { 
  name: string; 
}
type User = Name & { age: number  };

typeof 能夠獲取一個變量的聲明類型

在 JavaScript 中, typeof 能夠判斷一個變量的基礎數據類型, 在 TS 中,它還能夠獲取一個變量的聲明類型

const obj = { a'1' };
type Foo = typeof obj; 
// type Foo = { a: string }

keyof 能夠獲取一個對象接口的全部 key 值

type Obj = { a: string; b: string }
type Foo = keyof obj;
// type Foo = 'a' | 'b';

in 能夠遍歷枚舉類型

type Keys = 'a' | 'b' | 'c';
type Obj = { 
    [ T in Keys]: string;
}
// in 遍歷 Keys,併爲每一個值賦予 string 類型

// type Obj = {
//     a: string,
//     b: string,
//     c: string
// }

TS中一些內置的類型

官方文檔:https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt

用到了上面提到的一些關鍵詞

Partial<T> 將類型的屬性變成可選

功能是將類型的屬性變成可選,注意這是淺Partial

type Partial<T> = { 
    [P in keyof T]?: T[P] 
};

舉例說明

interface UserInfo {
    id: string;
    name: string;
}

// error:Property 'id' is missing in type '{ name: string; }' but required in type 'UserInfo'
const xiaoming: UserInfo = {
    name'xiaoming'
}

使用  Partial<T>

type NewUserInfo = Partial<UserInfo>;

const xiaoming: NewUserInfo = {
    name'xiaoming'
}

這個  NewUserInfo 就至關於

interface NewUserInfo {
    id?: string;
    name?: string;
}

可是 Partial<T> 有個侷限性,就是隻支持處理第一層的屬性,若是個人接口定義是這樣的

interface UserInfo {
    id: string;
    name: string;
    fruits: {
        appleNumber: number;
        orangeNumber: number;
    }
}

type NewUserInfo = Partial<UserInfo>;

// Property 'appleNumber' is missing in type '{ orangeNumber: number; }' but required in type '{ appleNumber: number; orangeNumber: number; }'.
const xiaoming: NewUserInfo = {
    name'xiaoming',
    fruits: {
        orangeNumber1,
    }
}

能夠看到,第二層之後就不會處理了,若是要處理多層,就能夠本身經過  Conditional Types[2]

DeepPartial

type DeepPartial<T> = {
     // 若是是 object,則遞歸類型
    [U in keyof T]?: T[U] extends object
      ? DeepPartial<T[U]>
      : T[U]
};

type PartialedWindow = DeepPartial<Window>; // 如今window 上全部屬性都變成了可選啦

Required 將類型的屬性變成必選

type Required<T> = { 
    [P in keyof T]-?: T[P] 
};

其中 -? 是表明移除 ? 這個 modifier 的標識。再拓展一下,除了能夠應用於 ? 這個 modifiers ,還有應用在 readonly ,好比 Readonly<T> 這個類型

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

Pick 從某個類型中挑出一些屬性出來

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
interface UserInfo {
    id: string;
    name: string;
}
type NewUserInfo = Pick<UserInfo, 'name'>; // {name: string;}

能夠看到 NewUserInfo 中就只有個 name 的屬性了。

Record

能夠得到根據 K 中全部可能值來設置 key 以及 value 的類型

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

舉個例子

type CurRecord = Record<'a' | 'b' | 'c', UserInfo>; // { a: UserInfo; b: UserInfo; c: UserInfo; }

Mutable<T> 將類型的屬性變成可修改

功能是將類型的屬性變成可修改,這裏的 -指的是去除。-readonly 意思就是去除只讀,也就是可修改啦。

type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

Readonly<T> 類型的屬性變成只讀

type Readonly<T> = { 
    readonly [P in keyof T]: T[P] 
};

ReturnType 用來獲得一個函數的返回值類型

type ReturnType<T extends (...args: any[]) => any> = T extends (
  ...args: any[]
) => infer R
  ? R
  : any;

infer在這裏用於提取函數類型的返回值類型。ReturnType<T> 只是將 infer R 從參數位置移動到返回值位置,所以此時 R 便是表示待推斷的返回值類型。

下面的示例用ReturnType獲取到 Func 的返回值類型爲 string,因此,foo 也就只能被賦值爲字符串了。

type Func = (value: number) => string;

const foo: ReturnType<Func> = "1";

更多參考TS - es5.d.ts[3]

參考

  • 細數 TS 中那些奇怪的符號 [4]
  • TypeScript中高級應用與最佳實踐 [5]
  • TS 中的內置類型簡述 [6]
  • TypeScript 的工具類型 [7]
  • 深刻理解 TypeScript [8]

參考資料

[1]

TypeScript Playground: https://www.typescriptlang.org/play

[2]

Conditional Types: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

[3]

TS - es5.d.ts: https://github.com/microsoft/TypeScript/blob/master/src/lib/es5.d.ts#L1431

[4]

細數 TS 中那些奇怪的符號: https://segmentfault.com/a/1190000023943952

[5]

TypeScript中高級應用與最佳實踐: https://juejin.im/post/6844903904140853255#heading-9

[6]

TS 中的內置類型簡述: https://github.com/whxaxes/blog/issues/14

[7]

TypeScript 的工具類型: https://zhuanlan.zhihu.com/p/78180787

[8]

深刻理解 TypeScript: https://jkchao.github.io/typescript-book-chinese/


送書活動

爲了感謝各位小星星們一直以來對 【牧碼的星星】的大力支持和確定,如今推出以下送抽獎送書活動。

獎項設置

《TypeScript 項目開發實戰》 1 本

本書是一本TypeScript進階實踐指南,經過 9 個實用項目,詳細講解如何使用TypeScript 3.0和不一樣的JavaScript框架開發高質量的應用程序。書中不只介紹TypeScript的核心概念與技術,還涵蓋AngularReact的一些新功能,以及GraphQL、微服務和機器學習等相關的新技術。

同時可點擊下方連接進行購買~

參與方式

參與方式很簡單,關注 【牧碼的星星】公衆號回覆 666, 參與抽獎

截止時間

  • 活動截止 2020年9月21號 中午12:00
  • 兌獎截止 2020年9月23號 中午12:00

舒適提示

請在開獎前添加個人微信,不然將沒法領取獎品。

  

本文分享自微信公衆號 - 牧碼的星星(gh_0d71d9e8b1c3)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索