在TypeScript中定義數組有兩種方式web
// 第一種方式是能夠在元素類型後面接上[]
const listOne: number[] = [1, 2, 3] // 第二種方式是數組泛型,Array[元素類型] const listTwo: Array<number> = [4, 5, 6] 複製代碼
類型斷言分做兩種形式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,而不容許使用尖括號方式數組
使用枚舉能夠清晰地表達咱們的意圖,好比 訂單的狀態開始是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成爲一種新的原生類型,就像基本類型 number
和 string
同樣設計
const symbolOne = Symbol('hello')
const symboTwo = Symbol('hello') symbolOne === symbolTwo // false 複製代碼
tips: 經過一樣的方式生成兩個symbol,也是不一樣的,由於symbol是惟一的code
泛型用於提高代碼的重用性咱們但願本身編寫的代碼,不管是模塊仍是組件,不只能支持當前設計的數據類型,並且也能支持未來的數據類型。這在大型系統中是很是基礎且重要的功能。因此咱們經常能在各類各樣的靜態類型語言中看到泛型設計,使得用戶能夠靈活地選擇但願支持的類型,而非侷限於某一種類型
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') 複製代碼
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 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屬性的一部分
讓咱們解釋一下上面代碼的意義
keyof
關鍵字能夠獲取T,也就是Person的全部屬性名,即['name','age']
extends
關鍵字讓泛型K繼承了Person的全部屬性名,即['name','age'],依託於
keyof
關鍵字完成了類型索引