Typescript 中的函数
Javascrip 中函数是一等公民
一、Javascript 中的两种常见的定义函数的方式
1、函数声明
function myFunc(x,y){
return x+y
}
2、函数表达式
let addFunc = function(x,y){
return x-y
}
二、Typescript 中定义函数可同时定义函数接收的参数类型和函数的返回值类型
function myFuncTs (x:number,y:number):number {
return x+y
}
let result = myFuncTs(12,13)
当函数的返回值类型没有指定时,typescript 会自动根据函数返回值推断返回类型
可以使用接口来定义一个函数需要符合的形状,如:
interface addFuncInteface{
(x:number,y:number):number
}
let addF : addFuncInteface = (left:number,right:number)=>{ return left + right }
三、可选参数
JavaScript里,函数的每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。在Typescript 中可以用 ? 定义函数的可选参数,需要注意的是,可选参数必须在必须参数之后,否则报错。
下面的例子中,name 参数是可选参数,可传可不传。
interface callbackInterface{
(result:any):void
}
function canChoiceParames(width:number,height:number,callback:callbackInterface,name?:string):object {
let tempObj = {
w:width,
h:height,
}
callback(tempObj)
return tempObj
}
let res = canChoiceParames(100,200,function(res){
},'myName')
四、默认参数
与可选参数不同的是,带默认值的参数不需要放在必须参数的后面
下面的例子中 height 参数默认100
function defaultParams(width:number,height:number = 100){
}
五、剩余参数
必要参数和默认参数有一个共同点:他们都只表示某一个参数。但是有时候会有同时操作多个参数的需求,或者你并不知道会有多少个参数会传进来。在JavaScript里,你可以使用 arguments来访问所有传入的参数。在Typescript 中可以把所有参数、或者某部分参数收集到一个变量里。注意剩余参数只能是最后一个参数。
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
上面的例子中restOfName参数为一个包含了剩余参数的数组,该数组为[“Samuel”, “Lucas”, “MacKinzie”]
六、函数重载
当函数入参使用联合类型同时返回值也有有多种类型时,函数重载允许对函数接受不同参数的数量和类型时作出不同的处理。
比如实现一个反转函数,输入为数字类型123时输出321,输入字符串类型 abc 时输出 cba
利用联合类型,该需求实现如下
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}else{
return x
}
}
这样虽然能实现需求,但是函数参数与返回值的说明不够直观。调用者容易迷惑,当传入函数的参数类型为number 时返回值的类型究竟是 number 还是string。
函数重载可以解答这样的疑惑,使函数的类型定义表达更加直观。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}else {
return x
}
}
前面两个reverse 是函数声明,最后一个reverse 是函数实现,有参数类型和返回值类型随意搭配的意思。前面两个 reverse 对函数进行了声明,第一个reverse声明的内容为,当传入函数的参数类型为number 时,函数返回值类型为number 类型;第二个 reverse 声明的内容为,当传入函数的参数类型为string 时,函数返回值类型为string。
下面是另一个例子,动手试一下吧。
同样的,前面几个testOverload为函数声明,最后一个testOverload为函数实现:
function testOverload(x:string,y:boolean):number;
function testOverload(x:string,y:number):string;
function testOverload(x:number,y:number):string;
function testOverload(x:number,y:boolean):number;
function testOverload(x:string | number, y:number|boolean) :string | number {
return x
}
let o1 = testOverload('string',false); // 此时 o1 类型为numer,鼠标移动到 o1 变量上可看到类型
let o2 = testOverload('string',10);// 此时 o2 类型为string,鼠标移动到 o2 变量上可看到类型
let o3 = testOverload(12,10);// 此时 o2 类型为string,鼠标移动到 o2 变量上可看到类型
let o4 = testOverload(13,true);// 此时 o2 number,鼠标移动到 o2 变量上可看到类型