距离上一次总结,鸽了很久了,一个原因是一直没有时间弄,另一个就是总结想起来容易,做起来真的很难,本能地排斥。不过该来的终究会来,就抓紧时间弄完吧。
ts函数类型
上一篇文章中已经介绍过函数类型的定义,这里总结一下函数参数,重载,this的情况。
可选参数
顾名思义,就是可有可无的参数了,需要注意的是必须放到最后,这和自己实现一个不确定参数函数时的做法是一样。
function optionFun(name: string, age?: number): void {
console.log(age ? `name: ${name}, age: ${age}` : `name: ${name}`)
}
参数默认值
顾名思义,就是给一个函数设置一个默认值,这样的话当未传入此参数时就会使用它的默认值。
function defaultValFun(name="zhangzongwei") {
console.log("name: ", name)
}
剩余参数
当出现参数不确定的情况时,就可以使用剩余参数。
function restArgsFun(...rest: any[]) {
console.log(isArray(rest))
}
函数重载
函数重载这个概念对于学过java的同学来说很熟悉,但在ts中又稍稍不一样。
// 定义一个重载列表,在编译的时候会逐个遍历匹配
function reloadFun(...rest: number[]) {}
function reloadFun(...rest: string[]) {}
// 定义一个调用函数,注意参数类型要为any
function reloadFun(...rest: any[]) {
// 判断参数的具体类型
if (typeof rest[0] === "number") return "number"
return "string"
}
this
this,算是js中的一个必须要搞懂的知识了,经常要思考this的指向,什么被动(隐式)绑定,主动(显式)绑定等。在ts中可以指定this指向哪儿。
interface People {
name: string,
getName: () => any
}
let princess: People = {
name: "duanshuqing",
getName(this: People) {
// 箭头函数的this是离它最近的函数中的this,例如这里的this就指向People
return () => {
console.log("name": this.name)
}
}
}
// 当然,如果指定this为void,则this不会指向任何类型
function voidThisFun(this: void) {
console.log("type": this.type) // 报错
}
ts泛型
泛型,这个概念在js中是没有,很明显是借鉴其他语言的特性。泛型从字面意思上理解就有一种不确定类型的感觉,只有在真正实现的时候才确定类型,这其实带来了很大的便利,例如对于一些可以拥有多种类型的变量来说,就不需要使用联合类型了;还有上面的函数重载,也没必要定义重载列表了。需要注意的是泛型是类型,而不是值。
泛型函数
// 可以给泛型设定默认类型
function genericsFun<T = string>(name: T): T {
return name
}
// 调用时确定类型
genericsFun<string>("zhangzongwei")
泛型接口
// 可以约定接口中的某一成员
interface genericsInter {
name: string,
getName: <T>(name: T) => T
}
let generics = {
name: "zhangzongwei",
getName(name: string) {
return name
}
}
// 也可以约定接口中所有成员
interface genericsInter2<T> {
name: T,
(str: T): T
}
泛型类
泛型类不能约定类中的静态成员。
class GenericsClass<T> {
constructor(name: T) {
this.name = name
}
name: T
getName(name: T) : void {}
// 报错
static age: T
}
// 创造一个实例时,就指定类型
let instance = new GenericsClass<string>("duanshuqing")
let instance2 : GenericsClass<string> = new GenericsClass("zhangzongwei")
// 也可以不指定类型,这时任意类型都可以
let instance3 = new GenericsClass(100)
泛型约束
当访问参数的某个属性时,需要对泛型进行约束,这样编译器才知道其拥有这个属性。
// 定义一个接口
interface Length {
length: number
}
// 对泛型进行约束
function getLength<T extends Length>(name: T) {
console.log("name length: ", name.length)
}
参考资料