1. 函数类型的基础定义
显式指定函数参数和返回值的类型
const add = (a: number, b: number): number => {
return a + b;
}
或者用type来声明函数类型
type addFnType = (a: number, b:number) => number;
let addFn: addFnType = (num1, num2) => {
return num1 + num2;
}
2. 函数参数类型
参数一般有:可选参数、默认参数、剩余参数;
1. 可选参数
在类型标注的:前添加?表示 log 函数的参数 x 就是可缺省的;
function log(msg?: string):void {
console.log(msg);
}
可缺省是不是相当于msg参数的类型就是和string | undefined等价呢?这个当然不是,string | undefined的意思是这两个类型中的一种,而可缺省是不传的意思。
2. 默认参数
function addFn1(num1: number = 1, num2: number = 2):number {
return num1 + num2;
}
函数的默认参数类型必须是参数类型的子类型
function log3(x: number | string = 'hello') {
console.log(x);
}
这里x参数的类型就是联合类型number | string,函数默认参数的类型就是联合类型的子类型
3. 剩余参数
function sum(...nums: number[]) {
return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2); // => 3
sum(1, 2, 3); // => 6
4. this
函数中的this问题,一直都是javascript最令人头疼的问题,因为this的指向只有函数调用的时候才能确定。还有一些可以改变this指向的方法(apply,call,bind)。
但是在Typescript中,必须要明确的指定this的类型(严格模式下)。
export {};
type objType = {person: (n: string) => void, myname: string};
// ts提供了Window(W大写)类型,而我们常用的window就是它的对象
function person(this: Window | objType , name: string):void {
//我们想要给window上添加东西,需要通过interface拓展,
//但是Window类型必须在全局(也就是不在是export{}一个空)才能接受拓展
//所以我们可以定义一个global.d.ts文件来专门写这种全局的拓展
this.myname = name;
console.log(this.myname);
}
window.person = person; //在本文件中我们写了export{},所以window仍然不是全局的,
//所以这里的函数person并没有挂载在window上,我们手动挂载
window.person('window name');
let obj:objType = {
person,
myname: ''
};
obj.person('obj name');
注意:为什么我们这里的this声明的类型是Window?因为它在最外层,而调用这个函数的也是window,this的类型必须和调用它的类型一致
单单是上面的代码是有问题的,我们还需要创建一个类型声明文件global.d.ts,(其实就是你随便写一个文件,这个文件不使用export{};让里面的代码暴露,因为window只有在全局下才能接受你的拓展)为window对象上扩展两个属性person、myname;
interface Window {
person: (n: string) => void;
myname: string;
}
定义对象的函数属性时,只要实际调用中 this 的指向与指定的 this 指向不同,TypeScript 就能发现 this 指向的错误
interface ObjType2 {
name: string;
say: (this: ObjType2) => void;
}
let obj2:ObjType2 = {
name: 'obj2',
say() {
console.log(this.name);
}
}
obj2.say(); // ok
let t11 = obj2.say;
t11();
注意:
- 显式声明函数的返回值类型为 undfined,则会出现错误提示,如果没有返回值,我们用void表示;
- 显式注解函数中的 this 类型,它表面上占据了第一个形参的位置,但并不意味着函数真的多了一个参数,因为 TypeScript 转译为 JavaScript 后,“伪形参” this 会被抹掉,这算是 TypeScript 为数不多的特有语法。