函数
TypeScript 为 JavaScript 函数添加了额外的功能,让我们可以更容易地使用。
函数类型
为函数定义类型
函数类型包含两部分:参数类型和返回值类型
// 具名函数
function add(x: number, y: number): number {
return x + y
}
// 匿名函数
let myAdd = function (x: number, y: number): number {
return x + y
}
TypeScript 能够根据返回语句自动推断出返回值类型,因此我们通常省略它。
完整函数类型
给函数的参数指定名字和类型,增加可阅读性
// 先指明了 myAdd 的类型,然后是一个函数
let myAdd: (baseValue: number, increment: number) => number = function (
x: number,
y: number
): number {
return x + y
}
只要参数类型匹配的,我们就认为他是有效的函数类型。返回值类型是函数类型的必要部分,如果函数没有返回值,必须指定返回值类型为void
,而不能留空
可选参数和默认参数
TypeScript 里的每个参数都是必须的,编译器会检查用户是否传递了值,并且传递给函数的参数个数与函数的期望个数是否一致
let res = add(1, 2, 3) // Expected 2 arguments, but got 3
let res1 = add(1) // Expected 2 arguments, but got 1
let res2 = add(1, 2) // right
在 JavaScript 中如果我们某个参数不传值,则默认这个参数的值为undefined
,但是在 TypeScript 中我们需要通过在参数名后面加 ?
来表示该参数是可选参数,可选参数必须放在必选参数的后面,这点很容易理解。
function add(x: number, y?: number): number {
if (y) return x + y
return x
}
let res = add(1) // right
当用户没有传递这个参数或者传递的参数为 undefined 时,我们可以为参数初始化一个默认值,这个在 es6 中已经有支持了,这点是一样的
function add(x: number, y = 1): number {
return x + y
}
let res = add(1)
在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。 也就是说可选参数与末尾的默认参数共享参数类型。带默认值的参数可以放在必选参数的前面,但是如果想要获得默认值,必须在调用的时候自己手动传递undefined
function add(x = 1, y: number) {
return x + y
}
let res = add(undefined, 1)
剩余参数
这个与 es6 中的...
一样的,剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个,名字是你在省略号( ...
)后面给定的名字,你可以在函数体内使用这个数组。剩余参数必须放在必选参数后面。
function add(x: number, ...rest: number[]) {
return rest
}
// 返回
let res = add(1, 2, 3, 4, 5) // [2,3,4,5]
this 和箭头函数
在 TypeScript 中如下使用 this
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),
// NOTE: The function now explicitly specifies that its callee must be of type Deck
createCardPicker: function (this: Deck) {
return () => {
let pickedCard = Math.floor(Math.random() * 52)
let pickedSuit = Math.floor(pickedCard / 13)
// 如果不在function的参数中这样指定this,当我们鼠标移到下面的this上显示的是 any,但是这样指定后就是Deck了
return { suit: this.suits[pickedSuit], card: pickedCard % 13 }
}
},
}
let cardPicker = deck.createCardPicker()
let pickedCard = cardPicker()
alert("card: " + pickedCard.card + " of " + pickedCard.suit)
为什么显示为 any 呢?这是因为 this
来自对象字面量里的函数表达式。 修改的方法是,提供一个显式的 this
参数。 this
参数是个假的参数,它出现在参数列表的最前面
重载
重载是面向对象语言实现多态的一种方式,所谓重载是指函数的名字一样,但是函数个参数个数或者类型不一致,我们在调用函数的时候,编译器会根据我们传递的参数去匹配对应的函数
function reloadFunc(a: number): void;
function reloadFunc(a: string): void;
function reloadFunc(a): any {
console.log(`这是${typeof (a)}的重载函数`)
}
reloadFunc(1)
reloadFunc("2")
reloadFunc({})
/* Overload 1 of 2, '(a: number): void', gave the following error.
类型“{}”的参数不能赋给类型“number”的参数。
Overload 2 of 2, '(a: string): void', gave the following error.
类型“{}”的参数不能赋给类型“string”的参数。ts(2769)
*/
它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。function reloadFunc(a): any
并不是重载列表的一部分,因此这里只有两个重载:一个是接受数字参数,一个是接受字符串参数,如果用别的方式调用就会报错