// 命名函数
function add(x: number, y: number): number {
return x + y
}
// 匿名函数
let add = function (x: number, y: number): number {
return x + y
}
let add: (baseValue: number, increment: number) => number =
function (x: number, y: number): number {
return x + y
}
如果在赋值语句的一边指定了类型而另一边没有,TypeScript
编译器会自动识别类型:
let myAdd = function (x: number, y: number): number {
return x + y
}
let myAdd: (x: number, y: number) => number =
function (x, y) {
return x + y
}
JavaScript
中参数可传可不传,如果没传,会默认为 undefined
。
但是 TypeScript
中必须传入的参数个数与函数期望的个数一致。
function buildName(firstName: string, lastName: string): string {
return firstName + ' ' + lastName
}
TypeScript
中使用 ?
来定义可选参数,可选参数只能放在必须参数之后,如果不传则值为 undefined
;undefined
来获取默认值。在 JavaScript
中可以通过 arguments
来访问所有传入的参数,
而在 TypeScript
中可以通过 剩余参数(...rest)
来获取传入的所有多余的参数组成的数组。
function printNumber(num: number, ...restNumbers: number[]): void {
console.log(num)
console.log(`restNumbers: `, restNumbers)
}
printNumber(1)
// 1
// restNumbers:
printNumber(1,2,3)
// 1
// restNumbers: 2,3
剩余参数是一个数组,会被当作个数不限的可选参数,可以一个都没有,此时为空数组。
带有剩余参数的函数定义:
let printNumberFun: (num: number, ...restNumbers: number[]): void = printNumber
箭头函数
=>
不是普通的function
, 没有独立的作用域,所以箭头函数中的this
是该箭头函数定义时所属的最近的一个作用域。
// case one: `this` 的指向在调用时才能确定
window.name = 'window'
let obj = {
name: 'yuusha',
printName: function() {
console.log(this.name)
}
}
obj.printName() // 'yuusha'
let foo = obj.printName
foo() // 'window'
// case two: 箭头函数中的this始终指向该箭头函数被创建时所在的作用域 【相当于普通函数使用bind(this)的效果】
let obj = {
name: 'yuusha',
printName: function () {
return () => {
console.log(this.name)
}
// 相当于:
/* return function(){
console.log(this.name)
}.bind(this) */
}
}
let foo = obj.printName()
foo() // 'yuusha'
let foo2 = obj.printName.call({name: 'tempName'})
foo2() // 'tempName'
TypeScript
支持给方法显式地提供一个 this
参数,放在参数列表最前面,限制该方法中的 this
的类型,从而避免一些错误:
interface UseThisDemo {
name: string
age: number
printInfo(this: UseThisDemo): void
}
let person: UseThisDemo = {
name: 'yuusha',
age: 24,
printInfo: function (this: UseThisDemo){
console.log(this.name, this.age)
}
}
person.printInfo()
// let foo = person.printInfo
// foo() // Error, `this` is not `UseThisDemo` type
let foo = person.printInfo.bind({name: 'xyz', age: 123, printInfo(){}})
foo() // OK, `this` refers to a `UseThisDemo` object
TypeScript
中允许为同一个函数提供多个函数类型定义来进行 函数重载。
// 根据传入参数的不同调用不同的处理函数
function getBirthYear(age: number): number
function getBirthYear(date: Date): number
function getBirthYear(x: number | Date): number {
if (typeof x === 'number') {
return new Date().getFullYear() - x
} else {
return x.getFullYear()
}
}
console.log(getBirthYear(24)) // 2019 - 24 = 1995
console.log(getBirthYear(new Date('1995-10-26'))) // 1995
注意:
function getBirthYear(x: number | Date)
不是重载的一部分,上面的代码只有两个重载: 一个接收数字,一个接收日期。- 定义重载时,最好将最精确的定义放在最前面,因为
TypeScript
编译器从前往后进行重载匹配。