TypeScript 基礎(記錄學習)

Array 數組

在TypeScript中定義數組有兩種方式web

// 第一種方式是能夠在元素類型後面接上[]
const listOne: number[] = [1, 2, 3]  // 第二種方式是數組泛型,Array[元素類型] const listTwo: Array<number> = [4, 5, 6] 複製代碼

Assertion 類型斷言

類型斷言分做兩種形式typescript

// 第一種用 "尖括號"
const stringOne: any = 'hello TypeScript' const stringOneLength: number = (<string> stringOne).length   // 第二種用 關鍵字 「as」 const stringTwo: any = 'hello TypeScript' const stringTwoLength: number = (stringTwo as string).length 複製代碼

tips: 在TypeScript的JSX中類型斷言可使用as,而不容許使用尖括號方式數組

Enum 枚舉

使用枚舉能夠清晰地表達咱們的意圖,好比 訂單的狀態開始是0,未結帳是1,運輸中是2,運輸完成是3,已收貨是4編輯器

數字枚舉

使用數字枚舉來完成訂單的狀態函數

enum OrderStatus {
 START,  UNPAID,  SHIPPING,  SHIPPED,  COMPLETE }  console.log(  OrderStatus.START, // 0  OrderStatus.UNPAID, // 1  OrderStatus.SHIPPING, // 2  OrderStatus.SHIPPED, // 3  OrderStatus.COMPLETE, // 4 ) 複製代碼

tips: 舉可讓咱們定義一些名字有意義的常量, 使用枚舉能夠清晰地表達咱們的意圖ui

字符串枚舉

enum OrderStatus {
 START = 'START',  UNPAID = 'UNPAID',  SHIPPING = 'SHIPPING',  SHIPPED = 'SHIPPED',  COMPLETE = 'COMPLETE' }  console.log(  OrderStatus.START, // START  OrderStatus.UNPAID, // UNPAID  OrderStatus.SHIPPING, // SHIPPING  OrderStatus.SHIPPED, // SHIPPED  OrderStatus.COMPLETE, // COMPLETE ) 複製代碼

tips: 因爲字符串枚舉沒有遞增的含義,字符串枚舉成員都必須手動初始化, 字符串枚舉能進一步提高可讀性,且在運行時中提供具備刻度性質的值es5

反向映射

enum Test {
 PRAISE }  console.log(  TEST.PRAISE, // 0  TEST[0] // 'PRAISE' )  // 緣由: 編譯器拿到這段代碼會編譯到JavaScript,是以下這樣的 (function (Enum) {  Enum[Enum['PRAISE'] = 0] = 'PRAISE' })(Enum || (Enum = {})) 複製代碼

tips: 在字符串枚舉中沒有反向映射spa

Symbol

symbol成爲一種新的原生類型,就像基本類型 numberstring 同樣設計

const symbolOne = Symbol('hello')
const symboTwo = Symbol('hello')  symbolOne === symbolTwo // false 複製代碼

tips: 經過一樣的方式生成兩個symbol,也是不一樣的,由於symbol是惟一的code

Generic 泛型

泛型用於提高代碼的重用性咱們但願本身編寫的代碼,不管是模塊仍是組件,不只能支持當前設計的數據類型,並且也能支持未來的數據類型。這在大型系統中是很是基礎且重要的功能。因此咱們經常能在各類各樣的靜態類型語言中看到泛型設計,使得用戶能夠靈活地選擇但願支持的類型,而非侷限於某一種類型

Fcuntion 泛型函數

function hello<T>(arg:T): T {
 return arg } console.log(  hello('string'),  hello(23),  hello({name: 'Praise'}) ) // string 23 { name: 'Praise' } 複製代碼

tips: 泛型變量T,T表明用戶即將傳入的類型。類型既能夠是number,也能夠是string,而在最後,咱們還使用T做爲返回值的類型。這就達到了返回 值和參數類型相同的目的,保持住了函數表達的準確性

使用泛型函數 有兩種方法能夠選擇

// 第一種 使用熟悉的尖括號方式進行表達
const optput = hello<string>('hello TypeScript')  // 第二種 使用類型推斷 const optput = hello('hello TypeScript') 複製代碼

Variable 泛型變量

function hello<T>(arg: T): T {
 console.log(arg.length) // error TS2339: Property 'length' does not exist on type 'T'.  return arg } 複製代碼

tips: 編譯器會很是迅速地進行報錯,告訴咱們泛型T並無length這個屬性

可使用泛型數組來表達這樣的狀況

// 中括號 表達
function hello<T>(args: T[]): T[] {  console.log(args.length)  return args }  // Array 表達 function hello<T>(args: Array<T>): Array<T> {  console.log(args.length)  return args } 複製代碼

Interface 高級類型

一個很經常使用的場景,好比函數傳參

interface IPraise {
 name: string  age: number  hobby: Array<string> }  function person(arg: IPraise): IPraise {  return arg }  console.log(  person({name: 'Praise', age: 23, hobby: ['code']}) ) 複製代碼

可選屬性

將一個已知類型的每一個屬性都變爲可選的,好比像這樣使用問號

interface IPraise {
 name?: string  age?: number  hobby?: Array<string> } 複製代碼

tips: 在實例化IPraise時,咱們沒必要給每一個屬性都賦值

只讀屬性

interface IPraise {
 readonly name: string  readonly age: number  readonly hobby: Array<string> } 複製代碼

索引簽名

在不肯定屬性數量的狀況下可使用索引簽名來添加一些額外的屬性

interface IPraise {
 name: string  age: number  hobby: Array<string>  [propName: string]: any } 複製代碼

tips: IPraise的屬性值都是隻讀不可修改的

交叉類型與聯合類型

type NewType = number & string
let newType: NewType  interface IPraiseOne {  name: string  age: number }  interface IPraiseTwo {  hobby: Array<string> }  type Praise = IPraiseOne | IPraiseTwo let praise: Praise 複製代碼

映射類型

在映射類型裏,新類型以相同的形式去轉換舊類型裏的每一個屬性。例如,你能夠令每一個屬性成爲只讀類型或可選類型

type Readonly<T> = {
 readonly [P in keyof T]: T[p] }  type Partial<T> = {  [P in keyof T]?: T[P] }  type PersonPartial = Partial<Person> type ReadonlyPerson = Readonly<Person> 複製代碼

tips: 內置的類型還有Required、Pick、Record、Exclude、Extract、NonNullable;讀者能夠本身嘗試這些類型方法,它們的實現都在typescript/lib/lib.es5.d.ts中

// 一個Lodash中常見的pluck函數,就是從對象中選取屬性的子集. 下面是pluck函數的簡化版示例
function pluck(obj, names) {  return names.map(name => obj[name]) } 複製代碼

若是須要在TypeScript中使用這個函數,要經過索引類型查詢索引訪問操做符:

function pluck<T, K extends keyof T>(obj: T, names: K[]): T[K][] {
 return names.map(name => obj[name]) }  interface Person {  name: string  age: number }  const person: Person = {  name: 'Praise',  age: 23 }  pluck(person, ['name']) // Praise 複製代碼

tips: 編譯器會檢查傳入的值是不是Person屬性的一部分

讓咱們解釋一下上面代碼的意義

  1. 泛型: 這裏有T和K兩種類型。根據類型推斷,第一個參數obj就是person,類型會被推斷爲Person
  2. 類型推斷: 第二個參數,咱們能夠從右往左進行閱讀。 keyof關鍵字能夠獲取T,也就是Person的全部屬性名,即['name','age']
  3. 類型索引: extends關鍵字讓泛型K繼承了Person的全部屬性名,即['name','age'],依託於 keyof關鍵字完成了類型索引
  4. 索引訪問操做符: 返回值的類型是T[K][],閱讀起來有點困難。它實際表述的意思是,變量T取屬性K的值的數組,其中T[K]就是索引訪問操做符
相關文章
相關標籤/搜索