function add(x: number, y: number): number {
return x + y;
}
let add = function (x: number, y: number): number {
return x + y;
}
在ts中函数类型指的是函数参数及返回值的类型
let foo: (x: string, y:string) => string = function(a:string, b:string) {
return a + b
}
函数类型的等号左边可以理解为函数签名,等号右边为函数实现
let bar: (x:string , y:string) => string = function(a, b) {
return a + b
}
bar(1, 'bar') //error 类型“1”的参数不能赋给类型“string”的参数
在js中函数的参数可以按照定义传参,也可以多传或者不传
function foo(arg1, arg2) {
// do nothing
return
}
foo() // ok arg1 === undefined arg2 === undefined
foo(1,2) // ok
foo(1,2,3)
但在ts中,类型检查器会严格检查参数类型以及参数个数,这意味着你在参数类型正确的前提下不能多传或者少传参数。
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // error, An argument for 'lastName' was not provided.
let result2 = buildName("Bob", "Adams", "Sr."); // error, 应有 2 个参数,但获得 3 个。
let result3 = buildName("Bob", "Adams"); // ah, just right
在ts中,函数参数定义时,可以使用可选参数,一般最佳实践是可选参数放在所有必传参数的后面,除了可选参数还有默认参数,及参数具有默认值。默认参数对顺序没有要求。
let fooBar:(f:string, b?:string) => void =
function(foo, bar = 'bar') {
console.log(foo + '-' + bar)
}
fooBar('foo', undefined) //foo-bar
fooBar('foo') // foo-bar
上面的例子将函数可选参数和默认参数结合使用,值得注意的是,如果默认参数在必须参数前,要想函数使用默认值必须明确传入undefined值,否则只传必须参数会抛出异常
function buildName(firstName = "Will", lastName: string) {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // error, too few parameters
使用...
展开剩余参数,这es6剩余参数的行为一致
function joinStr(s1:string, ...str:String[]):string {
return s1.concat('-').concat(str.join('-'))
}
console.log(joinStr('a',...['b','c','d'])) //a-b-c-d
this
ts中this也是有类型的,所以在使用函数时,需要注意this类型,常见的两种this类型定义,一种方式是定义为某个具体类型,另一种就是this:void
。否则在编辑器设置了–noImplicitThis标记时, 它会指出 this的类型为any这个错误。
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};
}
}
}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);
interface UIElement {
addClickListener(onclick: (this: void, e: Event) => void): void;
}
class Handler {
info: string;
onClickGood(this: void, e: Event) {
// can't use this here because it's of type void!
console.log('clicked!');
}
}
let h = new Handler();
uiElement.addClickListener(h.onClickGood);
重载
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面.