TypeScript学习总结之函数

函数的注解方式

函数声明的注解方式

注解 参数和返回值

1
2
3
4
5
6
7
8
9
10
11
12
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
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
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
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);

方式二:使用 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

函数的重载

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

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 重载的意义在于 表意更清楚


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!