let arr: [string,number] = ['haha',3]
enmu
類型enum Color { Red = 3, Blue, Green } let color = Color[0] console.log(color) // undefined let color2 = Color[3] console.log(color2) //red
能夠指定序號typescript
enum Color { Red = 3, Blue = 5, Green = 7 }
沒有返回值數組
function test ():void { console.log("void") }
undefined
和 null
undefined
是 null
的子類型,因此能夠賦值給它ide
let u: null = null let n: null= undefined
它是任何類型的子類型,=函數
let someValue: any = "hello world" // 此處就是類型斷言 // let length: number = (<string>someValue).length // 強制轉化 let someLength: number = (someValue as string).length //類型推斷 console.log(someLength)
剩餘參數ui
對象this
let o = { a: 'haha', b: 22 } let {a: newName1, b:newName2} = o // ==> let newName1 = o.a let newName2 = o.b //ts let {a,b}: {a: string, b:number} = o
function f({a,b = '3'} = {a = ''}):void {} f() f({}) 能夠不傳第一個數組,可是若是傳了必須就有值
數組rest
數組code
let arr = [3,4,5] let arr2 = [7,8,9] let arr3 = [...arr,...arr2] console.log(arr3)
對象對象
let obj = { name: 'kangkang', age: 32 } let obj2 = {...obj,class: 'four'} console.log(obj2)
同名屬性後面的值會覆蓋前面的值!!!繼承
//定義接口使用interface 須要定義接口的名字,接口不在乎屬性的順序,只在乎屬性名和值得類型 interface LabelValue { label: string } function printLabel (labelObject: LabelValue) { console.log(labelObject.label) } let obj = {name: 'kangkang', label: 'string'} printLabel(obj) // 傳進去的對象包含被檢測屬性
可選屬性必須在必須屬性後面,且可選屬性時可選的
interface value { x?: number, y?: string }
一些屬性只在定義時須要改變能夠選用只讀屬性
interface value { readonly x: number, readonly y: string }
typeScript會對對象自變量作額外的變量檢查,如何避開?
interface values { x?: string, y?: number } // let testValues: values = {xx: 'haah',x: 'haha',y: 333} let a = { xx: 'haah', x: 'haha', y: 333 } let testValues: values = a
或者
interface values { x?: string y?: number [popsName: string]: any } let a = { xx: 'haah', x: 'haha', y: 333 }
class Clock implements Clock { constructore(x: number, y: number) { } currentTime:Date newTime(d: time) { this.currentTime = d } }
何時該用靜態接口何時該用動態接口?
靜態類類型
interface ClockConstructor { new (x: number, y: numebr): Clock }
構造器裏的類型須要經過靜態類型來對其進行檢查,如上.
interface Father { color: string } interface Mother { phone: number } interface Son extends Father,Mother{ age: string } let person = {} as Son person.color = 'red' person.age = '12' person.phone = 32 console.log(person)
混合類型
interface Counter { (x:number): number interel: string reset() :void } function getValue(): Counter { let counter = (function(x: number ) { return x }) as Counter counter.interel = '32' counter.reset = function() {console.log('haha')} return counter } getValue().reset()
當一個接口繼承一個類的類型時,會繼承它的一些私有成員什麼的,因此當接口繼承類後,建立新類使用接口後若是新類沒有繼承原類直接指定此接口會致使一些私有屬性等沒有成功被繼承,從而報錯
class orset { private state: any } interface orsets extends orset { reset(): void } class test extends orset impelments orset{ reset(): void{ console.log("rest implement") } } // 未繼承orset類,缺乏私有屬性state // class test2 implements orset { // reset() { // console.log("error") // } // }
class person { name: string constructor(name: string) {this.name = name} sayName(a:string):void { console.log(this.name + a) } } class mary extends person { constructor(name: string) { console.log("構造函數執行...") // 調用父類構造函數 super(name); } sayName(a: string = "你好"): void { console.log("mary ..."); // 調用父類方法 super.sayName(a); } } let test = new mary('mary') test.sayName()
public
、 private
、 protected
私有成員實例及子類實例子類也不可訪問,可是保護成員的子類型能夠訪問父類
let seret = 'acdsdfadfa' class test { private name: string // constructor (name: string) { // this.name = name // } get names() { return this.name } set names(newName: string) { if(seret && seret === 'acdsdfdfa') { this.name = newName }else { console.log("它是穿山甲") } } } let newTest = new test() newTest.names = 'hah' // 我是穿山甲
靜態屬性時存在類的自己(可直接經過類來訪問它),不是在類的實例上
class instance { static origin = { x: 0, y: 0 }; scale: number; constrouctor(scale: number) { this.scale = scale; } calculateRadius(point: { x: number; y: number }) { // 直接經過類名去使用它 let xDist = point.x - instance.origin.x; let yDist = point.y - instance.origin.y return { xDist, yDist }; } }
抽象類裏面包含抽象方法,抽象方法不能被直接實現須要去派生類中實現
抽象類也不能被實例化
類也能夠做爲類型
abstract class city { city: string constructor (city:string) { this.city = city } // 抽象類的方法也須要在派生類中去實現 abstract sayCity() :void } // let x = new city() // 沒法建立抽象類的實例 class citys extends city { static adr: string = 'kangkang' constructor() { super('nanjing') } sayCity():void { console.log(this.city) } sayHello(value:string):void { console.log(value) } } // 此處的citys是實例類型 let x:citys = new citys() x.sayCity() x.sayHello('haha') // typeof citys是得到citys類 類型 let y: typeof citys = citys y.adr = 'hehe' let z: citys = new y() z.sayHello('hwhw')
匿名函數和命名函數
函數類型包含兩部分,一部分是參數類型一部分是函數返回類型
let pro:(name: string,age: number) => number = function(x: string,y:number):number { return age++}
function buildName(firstName: string, lastName? : string ) { if(lastName) { return firstName + lastName }else { return firstName } } let x = buildName('dai') console.log(x)
可選參數必須在必須參數的後面,而帶有默認參數的可選參數能夠在前面
剩餘參數
function buildName(firstName:string, ...rest: string[]){}
爲何須要泛型?泛型如何使用?
好比當你在函數中須要輸入和返回的類型統一可是你在未使用前還不肯定會是哪一種類型的時候
// 此時傳入的類型和返回的就不必定會相同了* function test (x:any) :any { return x + '' }
使用方法
let x1 = test<string>('string') let x2 = test('string')
當使用了T類型不存在的屬性後會報錯,咱們使用具備此屬性好比數組能夠
function list <T> (type: T) { return type.length //類型T上不存在屬性length } function list2<T>(type: T[]) { return type.length }
function list2<T>(type: T) { return type } interface iden <T> { (arg:T): T } let s: iden<number> = list2
將泛型的類型名放在類名的後面可讓裏面都可以使用這個類型的變量來定義
class iden<T> { name: string key: T add: (s:T) => T } let x = new iden<number>() x.add = function (s: number) { return s + 2 }
泛型不能夠做用於靜態屬性的
interface types { length: number } let s = function<T extends types>(s: T) { console.log(s.length) } s("33") s(22) // error 22不具備length屬性 s({length: 222})
類型約束(k必須是T的屬性才行)
function x<T, K extends keyof T>(obj: T, key: K) { return obj[key] } let obj = {a: 3, b: 4, c: 5} let s = x(obj,'b') let s2 = x(obj,'s') // error 類型s的參數不能賦值給類型 a| b| c的參數
class one { name: string } class two { age: number } class profile { key: number } class a extends profile { sayName: one } class b extends profile { sayAge : two } function createFn <T extends profile>(c: new() => T): T { return new c() } let test = createFn(b).sayAge.age let test2 = createFn(a).sayName.name
在聲明變量和參數類型以及返回類型的時候會出現類型推斷
考慮以下狀況
let x = [0,'a',null] // number | string | null
其中任意類型都可
以下狀況
class Mother {} class Son extends mother{ name: string } class Daughter extends mother{ name: string } let s = [new son(), new daughter()]
當咱們s
被推斷出mother
時上面這種寫法並不能實現
let s: Mother = [new son(), new daughter()]
window.onmousedown = function(event) { console.log(event.click) } // mouseEvent 上不存在click事件 window.onmousedown = function(event: any) { console.log(event.click); };
第一個會經過左邊來推斷右邊的類型,對於mousedown來講它不存在click事件,而你指定類型就會使得這樣的類型推斷失效
class Mother {} class Son extends mother { name: string; } class Daughter extends mother { name: string; } // Mother會做爲最佳通用類型 function x(): Mother[] { return [new Son(), new Daughter()] }
交叉類型
會將多個類型合併爲一個類型
聯合類型
調用方法須要去調用它們的公有方法
類型保護
類型判斷?