基礎篇就快速過一下...html
let s: string = 'i am string'
let n: number = 1
let b: boolean = true
// undefined 類型的變量只能被賦值爲 undefined // null 類型的變量只能被賦值爲 null // 賦值爲其餘類型會報錯 let ud: undefined = undefined let nu: null = null
// 沒有返回值的函數爲void // 聲明一個 void 類型的只能將它賦值爲 undefined 和 null const popup = (): void => { console.log('function no return') } let useless: void = undefined
// 能夠被任何值賦值, 聲明未指定類型的變量也爲 any let anyType: any = 'str'
let uk: unknown; // unknown 和 any 的主要區別是 unknown 類型會更加嚴格: 在對unknown類型的值執行大多數操做以前,咱們必須進行某種形式的檢查, 一般能夠用as斷言 而在對 any 類型的值執行操做以前,咱們沒必要進行任何檢查。 // 當 unknown 類型被肯定是某個類型以前,它不能被進行任何操做好比實例化
let arr1: (number | string)[] = [1, 2, 3, '2121'] let arr2: Array<number | boolean> = [2, 2, 2, true]
// 表示一個已知元素數量和類型的數組,各元素的類型沒必要相同;越界不能訪問 // 在函數的剩餘參數中定義參數的個數和類型 let t1: [string, number, boolean | string] t1 = ['hello', 123, false]
// 永不存在的值的類型 // never類型: 老是會拋出異常或不會有返回值的函數表達式或箭頭函數表達式的返回值類型 // 不能賦值給除了 never 類型的其餘類型, 不能接受其餘類型 const err = (msg: string): never => { throw new Error(msg) } // err('hahaahah')
let ss: symbol = Symbol('hello') console.log(ss)
let obj: {name: string, value: number} = { name: 'huhua', value: 1232 } let obj1: object = { name: '哈哈', value: 1232 } console.log(obj, obj1, obj.name) // console.log(obj1.name) // name 不在 object 上
let myAdd = (x: number, y: number): number => x + y let add = (x: number, y: number) => x + y // 類型推斷, 沒必要註明返回值類型 console.log(myAdd(1, 2), add(3, 100)) let compute: (x:number, y:number) => number // 定義函數類型 compute = (aaa, bbb) => aaa + bbb
枚舉: 咱們能夠理解爲一組常量的集合, 能夠幫助咱們解決一些硬編碼問題
特別是 if 語句中的判斷值vue
export enum EState { one = 1, two, three, four, five, six, seven } 能夠正反取值: EState['one'] === 1; EState[1] === 'one' 方便維護一個狀態數組; 另外在組件中能夠賦值給一個變量
enum Direction { Up = 'Up', Down = 'Down', Left = 'Left', Right = 'Right' } console.log(Direction['Right'], Direction.Up); // Right Up
enum StrNum { n = 0, y = 'yes' }
// 只須要對象的值時可使用常量枚舉, 提升性能 const enum Direction { Up = 'Up', Down = 'Down', Left = 'Left', Right = 'Right' } const up = Direction.Up console.log(up)
接口(Interfaces)用於對「對象的形狀(Shape)」進行描述
接口一般用來約束咱們定義的對象, 函數, 類的結構和類型react
// 賦值的時候,變量的形狀必須和接口的形狀保持一致(不能多也不能少,類型還必須一致) interface Person { readonly id: number // 只讀屬性 name: string age: number sex?: string // 可選屬性 [key: string]: any // 索引類型, 值爲任意屬性; 以上必須爲 any 的子級 }
只是約束函數的形狀, 沒有實質性的聲明和計算 interface Func { (x: number, y: number): number } let addSum1: Func addSum1 = (a, b) => a + b
// 不一樣類之間公有的屬性或方法,能夠抽象成一個接口, 來被類實現(implements) // 類必須實現接口中聲明的全部屬性;能夠定義接口未聲明的屬性 // 接口只能約束類的公有成員 public // 接口不能約束類的構造函數 interface Man { name: string age: number } class Huhua implements Man { // 類中聲明共有屬性 name!: string // 賦值斷言 age!: number constructor(name: string, age: number) { this.name = name this.age = age } eat() { console.log('eat food') } }
// 接口繼承接口 interface Alarm { alert(); } interface LightableAlarm extends Alarm { lightOn(); lightOff(); } // 接口繼承類 class Point { x: number; y: number; } interface Point3d extends Point { z: number; } let point3d: Point3d = {x: 1, y: 2, z: 3};
// function 聲明 function add(a:number, b: number) { return a + b } // 類型結構聲明, 表達式另外聲明 let add: (a: number, b: number) => number type Add: (a: number, b: number) => number interface IAdd { (a: number, b: number): number }
// 可選參數, 默認參數, 剩餘參數: 注意順序 function add(a: number, b = 100, c?: number) { return c ? a + b + c : a + b } function add(x: number, ...rest: number[]) { return x + rest.reduce((pre, acc) => pre + acc) }
同名函數多類型兼容, 根據參數的不一樣來實現不一樣功能, 進行匹配 function add(...rest: number[]): number function add(...rest: string[]): string function add(...rest: any[]): any { let first = rest[0] if (typeof first === 'string') { return rest.join('') } if (typeof first === 'number') { return rest.reduce((pre, acc) => pre + acc) } }
ts主要添加成員的類型註解和成員修飾符;
ES6中類的數據類型就是函數,類自己就指向構造函數, 其方法都定義在構造函數的 prototype 屬性上.咱們能夠經過 ClassName.prototype.xxx 去訪問git
class Car { // 實例屬性: 這樣聲明要有初始值 _wheel: number = 4 // 實例屬性成員構造器: 默認返回實例對象(即this) constructor(name: string) { this.name = name } // 只讀屬性 readonly oil: string = '汽油' // public 默認的: 成員是能夠被外部訪問 public name: string = 'car' // 實例方法 run() { console.log(this.name + 'runing...') } // 私有成員: 成員是隻能夠被類的內部訪問 private priv() { console.log('priv') } // 被保護成員: 成員是隻能夠被類的內部以及類的子類訪問 protected pro() {} // 靜態成員: 能夠被類名調用和其子類名調用 static seats: string = '座位' } let bz = new Car('benz') // 經過 new 來實例化 let bm: Car = new Car('bm') // 類的類型 console.log(Car.seats)
class Bmw extends Car { constructor(name: stirng, public color: string) { // 先調用父類的實例 super(name) this.color = color } } console.log(Bmw.seats)
抽象類沒法實例化, 通常做爲基類使用, 咱們能夠抽離其餘類的公共屬性和方法
寫入抽象類中github
abstract class Animal { // abstract 關鍵字是用於定義抽象類和在抽象類內部定義抽象方法 abstract say(): void; move(): void { console.log('i can move') } } class Dog extends Animal { // 聲明抽象類中的方法, 這裏子類能夠對父類方法進行重寫; 實現所謂的多態 say() { console.log('汪汪汪'); } } let dog1 = new Dog() dog1.say() // 汪汪汪 dog1.move() // i can move
不一樣類之間能夠有一些共有的特性,這時候就能夠把特性提取成接口(interfaces),用 implements 關鍵字來實現 // 類必須實現接口中聲明的全部屬性(至關於約束公有屬性);能夠定義接口未聲明的屬性 // 接口只能約束類的公有成員 public // 接口不能約束類的構造函數 interface Alarm { alert(); } interface Light { lightOn(); lightOff(); } class Car implements Alarm, Light { alert() { console.log('Car alert'); } lightOn() { console.log('Car light on'); } lightOff() { console.log('Car light off'); } }
泛型:在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定類型的一種特性。
在聲明的同時指定類型變量的類型值vuex
// 1.函數約束 // 類型T不須要預先指定 至關於any類型 // 保證輸入類型和返回值類型是一致的 彌補了any類型的缺點 function log<T>(v: T): T { return v; } let s: string = "generics"; let a = log(s); console.log(a); console.log(log(1111)); // 2.函數類型約束 // 聯合類型,類型別名與字符串字面量類型都是使用 type 進行定義。 // type Log = <T>(v: T) => T // 類型別名 interface Log { <T>(v: T): T; } let myLog: Log = log; console.log(myLog([1, 2, 3])); // 3.泛型接口 // 接口的全部屬性均可以受到泛型變量的約束 // 能夠傳入默認類型 interface IGeneric<T = string> { (v: T): T; } let IG1: IGeneric<number> = log; console.log(IG1(123)); // 4.泛型類 class GenericNumber<T> { // 泛型變量不能約束類的靜態屬性 // zeroValue: T = T; add(x: T, y?: T) { console.log(x); return x; } } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.add(1); let myG1 = new GenericNumber(); myG1.add("hello ts generics"); // 5.泛型約束 interface Length { length: number; } // T繼承Length接口, 這樣的話輸入的參數必須具備length屬性 獲取value.length就是合法的了 function ggg<T extends Length>(value: T): T { console.log(value, value.length); return value; } ggg('hello') ggg([1, 2, 3])
根據tsconfig.json的配置規則進行推斷, 上下文推斷, 類型斷言as, 雙斷言,
is關鍵字: xx is string, 賦值斷言 let x!: stringtypescript
不一樣變量相互賦值時的類型檢查
函數兼容: 參數個數, 參數類型, 返回值類型
接口兼容: 成員少能夠被賦值爲成員多的json
在特殊區塊使用肯定的類型屬性和方法segmentfault
1.instanceof if (c instanceof A) c.a 2.in if (c in C) c.a 3.typeof 函數的參數爲聯合類型 if (typeof arg === 'string') {} else {} 4.聲明類型保護方法 字面量
// 縮小類型的約束範圍; // 索引類型查詢操做符K keyof T: 聯合類型的集合; // 索引類型訪問操做符 T[K]; // 泛型約束 T extends U interface IObj { a: string b: number } let key: keyof IObj let k: IObj['a'] let iobj = { a: 1, b: 2, c: 'ccc' } // 泛型索引約束 function getObjValue<T, K extends keyof T>(obj: T, keys: K[]): T[K][] { return keys.map(key => obj[key]) } console.log(getObjValue(iobj, ['a', 'c'])); // console.log(getObjValue(iobj, ['a', 'd'])); 保錯
這裏是針對咱們在正式開發中使用 ts 的一些技巧及規範說明數組
// ts項目配置文件說明
https://segmentfault.com/a/11...
http://www.typescriptlang.org...
declare var 聲明全局變量 declare function 聲明全局方法 declare class 聲明全局類 declare enum 聲明全局枚舉類型 declare namespace 聲明(含有子屬性的)全局對象 declare interface 和 type 聲明全局類型 export 導出變量 export namespace 導出(含有子屬性的)對象 export default ES6 默認導出 export = commonjs 導出模塊, import xx = require('xxx') export as namespace UMD 庫聲明全局變量 declare global 擴展全局變量 declare module 擴展模塊
type Partial<T> = { [P in keyof T]?: T[P] }; type p = Partial<InterfaceXXX>
type T = Exclude<1 | 2, 1 | 3> // -> 2
type Foo = Omit<{name: string, age: number}, 'name'> // -> { age: number }
待更新...
本人是在 vue 項目中首先使用的, 發現支持並非很好...可是仍是咬牙寫完了一個項目, 後續打算在 react使用一下
相關插件文檔
vue-class-component:
https://github.com/vuejs/vue-docs-zh-cn/tree/master/vue-class-component
vue-property-decorator:
https://github.com/kaorun343/vue-property-decorator
vuex-class:
https://github.com/ktsn/vuex-class
vuex-module-decorators
https://github.com/championswimmer/vuex-module-decorators
<類型>值 => <string> value 值 as 類型 => value as string (this.$refs['multiTable'] as any).clearSelection() (this.$refs['downParams'] as Form).resetFields()
((this.$refs.saveTagInput as Vue)['$refs'].input as HTMLInputElement).focus()