函数类型
1.为函数定义类型
我们可以给函数定义类型,这个定义包括对参数和返回值的类型定义
//参数类型为 string,返回值类型为 number
const getLength=(str:string):number=>str.length;
console.log(getLength("duke"));//4
2.完整的函数类型
我们需要为函数赋给的变量定义完整的函数类型,即包括参数类型和返回类型;
函数中如果使用了函数体之外定义的变量,这个变量的类型是不体现在函数类型定义的
3.使用接口定义函数类型
使用接口可以清晰的定义函数类型
interface Animal{
(a:string):string;
}
const Dog:Animal=dog=>dog+"汪汪汪";
4.使用类型别名
我们可以使用类型别名来定义函数类型,使之更加直观易读
type Add=(x:number,y:number)=>number;
let add:Add=(arg1:string,arg2:string):string=>arg1+arg2;
//error 不能将类型"(arg1:string,arg2:string):string"分配给类型 Add
使用type
关键字可以为原始值、联合类型、元组以及任何我们定义的类型起一个别名。
参数
1.可选参数
TS 会帮我们在编写代码的时候就检查出调用函数时参数中存在的一些错误;
接口形式定义的函数类型必选参数和可选参数的位置前后是无所谓的,但是 type 关键字定义的可选参数必须放在必选参数后面,这和 JS 中定义函数是一致的。
type Add=(x?:number,y:number)=>number;
//error 必选参数不能位于可选参数后
2.默认参数
const add=(x:number,y:number=2)=>{
return x+y;
}
3.剩余参数
在 JS 中,如果我们定义一个函数,这个函数可以输入任意个数的参数,那么我们就无法在定义参数列表的时候挨个定义
在 ES6发布之前,我们需要用到 arguments 来获取参数列表。arguments 是每一个函数都包含的一个类数组对象。
const handleData=(arg1,...args)=>{
console.log(args);
}
handleData(1,2,3,4,5);//[2,3,4,5]
可以看到,args 是除了 arg1之外的所有实参的集合,它是一个数组
在 TS 中你可以为剩余参数指定类型:
const handleData=(arg1:number,...args:number[])=>{
//
}
handleData(1,"a");
//error 类型"string"的参数不能赋给类型"number"的参数
函数重载
函数重载是指定义几个函数名相同,但是参数个数或类型不同的函数,在调用时传入不同的参数,编译器会自动调用适合的函数。
JS 作为一个动态语言是没有函数重载的,只能我们自己在函数体内通过判断参数的个数、类型来指定不同的处理逻辑。
在 TS 中有函数重载的概念,但并不是定义几个同名实体函数,然后根据不同的参数格式或类型来自动调用相应的函数。
TS 的函数重载是在类型系统层面的,是为了更好地进行类型推断。TS 的函数重载通过为一个函数指定多个函数类型定义,从而对函数调用的返回值进行检查。
function handleData(x: string): string[]; // 这个是重载的一部分,指定当参数类型为string时,返回值为string类型的元素构成的数组
function handleData(x: number): string; // 这个也是重载的一部分,指定当参数类型为number时,返回值类型为string
function handleData(x: any): any { // 这个就是重载的内容了,他是实体函数,不算做重载的部分
if (typeof x === "string") {
return x.split("");
} else {
return x
.toString()
.split("")
.join("_");
}
}
handleData("abc").join("_");
handleData(123).join("_"); // error 类型"string"上不存在属性"join"
handleData(false); // error 类型"boolean"的参数不能赋给类型"number"的参数。