函数定义
直接定义
直接定义这种方式是最好理解的。
function fun_1(num1: number, num2: number): number {
return num1 + num2;
}
const fun_2 = (num1: number, str1: string): string => {
return num1 + str1;
};
function fun_3(): void {
console.log("fun_3");
}
通过表达式定义
const fun_4: (num1: number, str1: string) => string = (num1: number, str1: string) => {
return num1 + str1;
};
通过类型别名定义
我们还可以把函数表达式定义成类型别名。
type fun5Type = (num1: number, str1: string) => string
const fun_5: fun5Type = (num1: number, str1: string) => {
return num1 + str1;
};
函数参数
函数参数这块在JS
中都有与之对应的特性,基本上差不多。
可选参数
type Add = (x: number, y: number, z?: number) => number;
let add: Add = (arg1, arg2, arg3) => arg1 + arg2 + arg3;
add(1, 2); // success 3
add(1, 2, 3); // success 6
在JavaScript
中,上面代码中后面两个函数调用都不会报错, 只不过add(1, 2, 3)
可以返回正确结果3
,add(1)
会返回NaN
。而在TypeScript
中我们设置了指定的参数,那么在使用该类型时,传入的参数必须与定义的参数类型和数量一致。
但有时候,函数有些参数不是必须的,我们就可以将函数的参数设置为可选参数。可选参数只需在参数名后跟随一个?
即可,这就是可选参数。
需要注意,可选参数必须放在必选参数后面,这和在 JS
中定义函数是一致的。来看例子:
type Add2 = (x?: number, y: number) => number; // error 必选参数不能位于可选参
// 需要改成
type Add2 = (y: number, x?: number) => number;
默认参数
当为参数指定了默认参数时,TypeScript
会识别默认参数的类型;当调用函数时,如果给这个带默认值的参数传了别的类型的参数则会报错:
const add = (x: number, y = 2) => {
return x + y;
};
add(1, "ts"); // error 类型"string"的参数不能赋给类型"number"的参数
当然也可以显式地给默认参数 y
设置类型:
const add = (x: number, y: number = 2) => {
return x + y;
};
默认参数不比可选参数,默认参数可以放在参数列表的任意位置。
const add = (x: number = 2, y: number) => {
return x + y;
};
当默认参数不在参数列表的第一个的时候我们该怎么使用呢?
// 使用undefined占位就可以啦
add(undefined, 10) // 12
剩余参数
剩余参数与JavaScript
中的语法类似,需要用 ...
来表示剩余参数。
const add = (a: number, ...rest: number[]) => rest.reduce(((a, b) => a + b), a)
上面的例子参数 rest
则是一个由number
组成的数组,在本函数中用 reduce
进行了累加求和。
函数重载
学过java
的通过肯定知道函数的重载和重写。
那么在 TypeScript
中函数重载是怎么定义的呢?
其实跟java
也是类似的,就是相同的方法名,只是方法参数列表不一样。和java
的区别就是 TypeScript
只能是最后有一个方法来完整实现,而不是每个方法都有对应的实现。
interface Direction {
top: number;
bottom?: number;
left?: number;
right?: number;
}
// 参数列表可能的情况 1个参数 2个参数 4个参数,只需定义,不需要实现
function assigned(all: number): Direction;
function assigned(topAndBottom: number, leftAndRight: number): Direction;
function assigned(
top: number,
right: number,
bottom: number,
left: number
): Direction;
// 方法完整的实现
function assigned(a: number, b?: number, c?: number, d?: number) {
if (b === undefined && c === undefined && d === undefined) {
b = c = d = a;
} else if (c === undefined && d === undefined) {
c = a;
d = b;
}
return {
top: a,
right: b,
bottom: c,
left: d,
};
}
assigned(1);
assigned(1, 2);
assigned(1, 2, 3); // 没有定义三个参数的函数,编译阶段直接报错
assigned(1, 2, 3, 4);
最后我们分别传入不同数量的参数,发现只有在三个参数的情况下报错了。因为我们没有定义三个参数的方法。
相较于JS
,函数重载可以让我们在编写代码阶段就能及时发现错误。很大的提升了我们的开发效率。
is关键字
is关键字一般和函数搭配使用。
我们来看个例子
function isString(test: any): boolean {
return typeof test === 'string';
}
function example(foo: number | string){
if(isString(foo)){
console.log(foo.length); // string function
}
}
example('hello world');
我们看到由于foo: number | string
是string
和number
的联合类型,后面又直接使用了.length
属性,所以会报错。
那有什么办法可以解决呢?
第一种我们可以使用类型守卫来解决。比如说使用typeof
。如果对类型守卫不了解的可以看看TypeScript学习之类型推断、类型断言、双重断言、非空断言、确定赋值断言、类型守卫、类型别名。
function example(foo: number | string) {
if (isString(foo) && typeof foo === "string") {
console.log(foo.length); // string类型才有length属性
}
}
第二种就是使用我们的is
关键字。
function isString(test: any): test is string {
return typeof test === 'string';
}
function example(foo: number | string){
if(isString(foo)){
console.log(foo.length); // string function
}
}
example('hello world');
我们在isString
方法后面不再返回boolean
类型而是test is string
。这句话什么意思呢?
意思就是如果isString
方法返回true
,就表示参数test
是string
类型的。所以后面直接调用.length
属性就不会报错。
系列文章
TypeScript入门之类型推断、类型断言、双重断言、非空断言、确定赋值断言、类型守卫、类型别名
后记
感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!