学习typescript-----基础
ts支持js中几乎所有的数据类型,还提供了额外的枚举类型
js数据类型: string、boolean、number、undefined、null、symbol和object
boolean
let bool:boolean = true
string
let str: string = 'abc'
let sayhi: string = `hi, my name is ${str}`
number
let n: number = 10 let n1: number = '0b0101' let n2: number = '0o4567' let n3: number = '0x34cde' let n4: number = 'NaN'
空
ts中的空(void)一般用来表明没有任何返回值的函数
function abc(): void{ console.log(123) }
null和undefined
null和undefined是所有类型的子类型,可以赋值给任意类型
任意值
let a:any = 'str' a = 123
在任意值上访问任何属性都是允许的
a.abc().def.ghj()
初始化时未指定类型和未赋值,默认就会给any类型
类型推论
ts会在没有明确给定类型的时候,推测出一个类型。
联合类型
联合类型表示取值可以取限定类型中的一种
let abc: string|number abc = 'abc' abc = 123
如果访问联合类型中的属性或方法,只能访问此联合类型所有类型中共有的属性或方法
对象类型-接口
ts的接口可以对类的一部分进行抽象,还可以对对象进行描述
interface Person{ name: string age: number } let obj: Person = { name: 'abc', age: 10 }
接口一般建议首字母大写, 使用时所定义的变量必须和接口规定的变量保持一致, 多属性或者少属性都是不允许的。
可选属性
interface Person{ name: string age?: number }
但仍然不允许添加未定义的属性
任意属性
interface Person { name: string age?: number [propName: string]: any }
[propName: string]定义了任意属性取string类型的值
注意: 一旦定义了任意属性,确定属性和可选属性的类型都必须是它的类型的子级
一个接口中只能有一个任意类型
只读属性
interface Person{
readonly name: string
}
数组类型
在ts中,定义数组的方式有很多种
1,类型+方括号 let arr: number[] = [1,2,3,4,5] 数组的项中不允许出现其他的类型 数组的方法也会进行类型的限制 可以使用any来允许数组中出现任意类型 let arr: any[] = [1, 'ab', {a: 1}] 2,数组泛型 let arr: Array<number> = [1,2,3,4,5] 3,用接口表示 interface Array{ [index: number]: number } 类数组: Interface Arguments { [index: number]: number length: number callee: Function } // 注: 这里为什么任意类型为number, callee却是Function, Function并不是number的子类型。 答:因为index指定的是number类型, callee是string, 不受index的number类型的影响
函数类型
函数是js中的一等公民
函数表达式
function abc (x: string, y: number): void { console.log(x, y) }
调用时输入多余或者少的参数是不允许的。
函数声明
const fn: (x: number, y:string) => void = function (x:number, y: string): void { console.log(x, y) }
请注意 ts类型定义中的 => 和 es6 箭头函数的区别
ts中 =>用来表示函数的定义, 左边是输入类型,右边是输出类型
也可以用接口的方式来定义函数类型
interface Fn {
(x: number, y: string): boolean
}
let myFn: Fn
myFn = function (x: number, y: string): boolean(){ return false }
可选参数
可选参数与接口中的可选属性类似, 用?:来表示,需要注意的是,可选参数必须是在必须参数的后面,也就是说可选参数后面不允许出现必须参数了
参数默认值
function fn(x:string = 'abc', y:number): void { console.log(x, y) } ts会将添加了默认值的参数识别为可选参数, 此时可选参数就不用必须放在必须参数后面了。
reset参数
...items: any[], reset参数必须是最后一个参数
重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理
类型断言
值 as 类型
类型断言的用途
1,将一个联合类型断言为其中一个类型
在ts中,如果不确定一个联合类型的变量到底是什么类型时,只能访问此联合类型所有类型中共有的方法或属性。
而有时候我们需要在还不确定类型的时候,就访问其中一个特有的属性或者方法,此时就需要用到类型断言
interface Fish{ name: string, swim(): void } interface Cat{ name: string, run(): void } function goSwim (animal: Fish | Cat) { if (animal.swim) { return true } // 报错 Cat上没有swim return false } function goSwim (animal: Fish|Cat) { if ((animal as Fish).swim) return true // 正确 return false }
断言只能欺骗ts编译器,并不能避免运行时的错误。
2,将一个父类断言为更加具体的子类
class ApiError extends Error { code:number = 0 } class HttpError extends Error { statusCode: number = 200 } function isApiError (error: Error) { if (typeof (error as ApiError).code === 'number') { return true } return false }
3,将任何类型断言为any
window.abc = 1 // 报错 window上没有abc (window as any).abc = 1 // 正确, 在any类型上访问任何属性都可以
4,将any断言为一个具体的类型
function getData(key: string): any { return (window as any)[key] } interface Cat { name: string run(): void } let tom = getData('tom') as Cat tom.run() tom.name
类型断言的限制
由上所知:1,联合类型可用被断言为其中一个类型, 2,父类可以被断言为子类 、3,任何类型都可以被断言为any、4,any可以被断言为任何类型
类型断言的限制: 如果A兼容B,则A可以断言为B,B也可以断言为A
双重断言
既然任何类型可以断言为any, any可以断言为任何类型
那么可以用as any as来将一个类型断言为任何其他类型 interface A { name: string } interface B { age: number } function test(testA: A) { return (testA as any as B) } 一般使用到双重断言,十有八九是错误的,会导致运行时报错
类型断言 vs 类型转换
function toBoolean (p: any): boolean { return p as boolean } toBoolean(111) // 返回的还是 111 这样做可以通过编译,但是并没有什么用 所以类型断言并不会真的影响到变量的类型
类型断言 vs 类型声明
类型声明比类型断言更加的严格。
a 断言为 b : 只需要满足a兼容b或者b兼容a
a 声明为 b :只有b兼容a才可以
内置对象
1,ECMAScript的内置对象 let b:Boolean = new Boolean(0) let e: Error = new Error('error') let d: Date = new Date() let r: RegExp = /\d/g 2,BOM和DOM的内置对象 let body: HTMLElement = document.body let divs: NodeList = document.querySelectorAll('div') document.addEventListener('click', function(e: MouseEvent){})
3, 核心库的定义
Math.random()