函数
定义函数
TypeScript支持两种定义函数方式,有名字的函数和匿名函数,和JavaScript相同:
// Named function
function add(x, y) {
return x + y;
}
// Anonymous function
let myAdd = function(x, y) {
return x + y;
};
函数参数类型定义和函数类型
函数类型包括完整的参数类型和返回值类型,下面例子中我们定义了一个函数对象变量myAdd,并立即将类型(x:number, y:number)=>number指定给它,然后使用function创建一个函数并赋值给myAdd。
当然,针对下面例子,直观感觉这么写没什么必要,因为变量定义和函数对象定义写在一起,函数定义时已经指定一次参数类型和返回值类型了。对此我们不必担心,如果myAdd不写完整的函数类型,TypeScript编译器也能根据后面函数定义推断出正确的类型。
let myAdd: (x:number, y:number)=>number =
function(x: number, y: number): number {
return x+y;
};
可选参数和默认参数
正常定义的每个函数参数都是必须的,不同于JavaScript。TypeScript中,使用?实现可选参数功能。例子:
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
let result1 = buildName("Bob"); // works correctly now
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result3 = buildName("Bob", "Adams"); // ah, just right
注意:可选参数必须放在后面。
参数默认值例子:
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"
let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result4 = buildName("Bob", "Adams"); // ah, just right
注意:
- 可选参数和默认参数共享参数类型。
- 带默认值的参数允许不放在所有普通参数后面,用户可以传入undefined获取默认值(和ES6相同),但最好不要这么干。
变长参数
JavaScript中通过arguments获得参数列表,TypeScript则是这样定义:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
this
this的值在函数被调用时才会指定,这在返回一个函数时会造成bug,详细请参考JavaScript精粹章节。TypeScript中有同样的用法。在EcmaScript6中,可以使用Lambda表达式(箭头函数),箭头函数不会覆盖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);
return {suit: this.suits[pickedSuit], card: pickedCard % 13};
}
}
}
注意:显式的this参数是为了避免this的类型为any。
重载
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
// Check to see if we're working with an object/array
// if so, they gave us the deck and we'll pick the card
if (typeof x == "object") {
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
// Otherwise just let them pick the card
else if (typeof x == "number") {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
注意:
- 重载是按参数列表,从上到下匹配的。应该把精确定义放到前面。
- function pickCard(x): any并不是重载的一部分。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。