TypeScript学习总结之函数


TypeScript

函数的注解方式

函数声明的注解方式

注解 参数和返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function test(a: number, b: number): number {
return a + b
}


function test1(a: number, b: number): void {
console.log(a + b);
}


function test2(a: number, b: number): never {
console.log(a + b);
throw new Error()
}

函数表达式的注解方式

// 不用给 function 后边写注解, 因为会根据前边的注解来做类型推断

1
2
3
4
5
6
7
8
9
10
11
12
13
let test: (a: number, b: number) => number = function (a, b) {
return a + b
}

let test1: (a: number, b: number) => void = function (a, b) {
console.log(a + b);

}

let test2: (a: number, b: number) => never = function (a, b) {
console.log(a + b);
throw new Error()
}

可选参数和默认参数

// 默认:传递给一个函数的参数个数必须与函数期望的参数个数一致。

1
2
3
4
5
6
7
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}

let result1 = buildName("Bob"); // 少一个参数 // error, too few parameters
let result2 = buildName("Bob", "Adams", "Sr."); // 多一个参数 // error, too many parameters
let result3 = buildName("Bob", "Adams"); // ah, just right

可选参数

// 注意:可选参数必须要放在必选参数的后边,否则会报错。

1
2
3
4
5
6
7
8
9
10
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}

let result1 = buildName("Bob"); // is OK
let result2 = buildName("Bob", "Adams", "Sr."); // 错误,多个一参数
let result3 = buildName("Bob", "Adams"); // is OK

默认值

1
2
3
4
5
6
7
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"
console.log(result1, result2); // Bob Smith Bob Smith

剩余参数

// …restOfName: string[] 一定要放在最后边,和ES6的扩展运算符一样

1
2
3
4
5
function buildName(firstName: string, lastName = 'Smith', ...restOfName: string[]) {
return firstName + " " + lastName + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas");

解构赋值在TS中的使用

1
2
3
4
5
6
function test(
{ a, b }: { a: number, b: number } = { a: 1, b: 2 }
) {
return a + b
}
console.log(test()); // 3

this指向

有时候我我们需要在函数中使用this来去指定那个示例对象, TS提供俩种方式

方式一: 使用箭头函数 + 配置noImplicitThis = true (不配置 this是any)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker: function () {
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);

return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
}
}
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

this

方式二:使用 interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface Card {
suit: string
card: number
}
interface Deck {
suits: string[]
cards: number[]
createCardPicker(this: Deck): () => Card
}

let deck: Deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker: function () {
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);

return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
}
}
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

这样 this 就会指向 Deck

this指向

函数的重载

// 官网的例子太麻烦了, 我以 翻转字符串或者数字来举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 翻转 字符串或者数字
function reverse(foo: string): string
function reverse(foo: number): number
function reverse(foo: string | number) {
if (typeof foo === 'string') {
return foo.split('').reverse().join('')
}

if (typeof foo === 'number') {
return Number(foo.toString().split('').reverse().join(''))
}
}
console.log(reverse(‘123456’)); // 字符串类型的 '654321'
console.log(reverse(123456)); // 数字类型的 654321

看着是不是好像没什么太大的区别?

// 其实 typescript 重载的意义在于 表意更清楚