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()] }
交叉类型
会将多个类型合并为一个类型
联合类型
调用方法须要去调用它们的公有方法
类型保护
类型判断?