1.函数类型定义
(1)直接定义
function add(arg1: number, arg2: number): number {return x + y;}const add = (arg1: number, arg2: number): number => {return x + y;};
如果省略了参数类型,Typescript 就会认为是any 类型,如果省略返回值类型,如果函数无返回值,Typescript 就会默认返回值类型时 void类型,如果有返回值,就会根据返回值类型推出类型。注意,如果没有返回值不能给他定义为 undefined 类型,必须是 void类型。
function hello(name: string):void{ // 没有返回值就是 voidconsole.log(name)}
(2)变量定义
let add: (x: number, y: number) => number;add = (arg1: number, arg2: number): number => arg1 + arg2;add = (arg1: string, arg2: string): string => arg1 + arg2; // error
定义一个add变量,给他定义了一个函数类型,这个函数类型包括函数的参数类型和函数的返回值类型,然后给add赋值了一个实际的函数,这个实际函数和定义的函数类型一致。如果不一致就会报错。
(3)接口定义
interface Add{(x: number, y: number): number}let tfn: Add = (x:number, y:number): number =>{return x+y}let add: Add = (arg1: string, arg2: string): string => arg1 + arg2;// error 不能将类型“(arg1: string, arg2: string) => string”分配给类型“Add”
通过接口定义的函数类型,再赋值给一个变量时,这个变量要实现符合这个接口定义的函数,不然会报错。
(4)类型别名定义
类型别名定义函数更加直观易读:
type Add3 = (x:number, y:number) => numberlet add3: Add3 = (arg1: number, arg2: number):number => arg1 + arg2
使用 type 关键字为函数类型定义了一个别名,然后指定 add 为 Add类型,如果赋值不满足Add类型就会报错。
2.函数参数定义
(1)可选参数
TypeScript里的每个函数参数都是必须的。 这不是指不能传递 null或undefined作为参数,而是说编译器检查用户是否为每个参数都传入了值。 编译器还会假设只有这些参数会被传递进函数。 简短地说,传递给一个函数的参数个数必须与函数期望的参数个数一致。
function buildName(firstName: string, lastName: string) {return firstName + " " + lastName;}let result1 = buildName("Bob"); // error, too few parameterslet result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameterslet result3 = buildName("Bob", "Adams"); // ah, just right
JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。 在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。 比如,我们想让last name是可选的:
function buildName(firstName: string, lastName?: string) {if (lastName)return firstName + " " + lastName;elsereturn firstName;}let result1 = buildName("Bob"); // works correctly nowlet result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameterslet result3 = buildName("Bob", "Adams"); // ah, just right
(2)默认参数
在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。 它们叫做有默认初始化值的参数。 让我们修改上例,把last name的默认值设置为”Smith”。
function buildName(firstName: string, lastName = "Smith") {return firstName + " " + lastName;}let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameterslet result4 = buildName("Bob", "Adams"); // ah, just right
当为参数指定了默认参数时,Typescript 会推断出这个参数的类型,如果给这个默认参数传递别的参数类型就会报错:
function buildName(firstName: string, lastName = "Smith") {return firstName + " " + lastName;}console.log(buildName('hhh', 12)) // 类型“12”的参数不能赋给类型“string | undefined”的参数。ts(2345)
(3)剩余参数
在JavaScript里,你可以使用 arguments来访问所有传入的参数。
在TypeScript里,你可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) {return firstName + " " + restOfName.join(" ");}let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
3.函数重载
JavaScript 可以在函数体内根据传入的参数个数或者类型而返回不同的数据。
let suits = ["hearts", "spades", "clubs", "diamonds"];function pickCard(x): any {if (typeof x == "object") {}else if (typeof x == "number") {}}
在 Typescript中 我们可以为同一个函数定义多个函数定义,根据函数的参数和返回值不同来调用哪一个函数。这就是函数重载。
function handleData (x: string): number;function handleData (x: number): string;function handleData (x: null): number;function handleData (x: string | number | null): any => {if (typeof x === 'string') {return Number(x);}if (typeof x === 'number') {return String(x);}return -1;};handleData(996) // "996"handleData("996") // 996handleData(false) // error
使用function 关键字定义了三个同名函数,第四个是这个函数定义的实体函数。包括函数名、函数参数、函数返回值。这样改变后,重载的 handleData 函数在调用的时候会进行正确的类型检查。
为了让编译器能够选择正确的检查类型,它与JavaScript里的处理流程相似。 它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
