函数
带类型的函数
function add(x: number, y: number): number {
return x + y;
}
let myAdd = function(x: number, y: number): number { return x + y; };
将函数付给变量时,也可在左侧同时指出变量类型,称为写出完整函数类型,但一般情况下ts会自动推断左侧的类型,无需手动指出。
参数
可选参数
TypeScript里的每个函数参数都是必须的。传递给一个函数的参数个数必须与函数期望的参数个数一致。
JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。在TypeScript里我们可以在参数名旁使用 ?
实现可选参数的功能。
可选参数必须跟在必须参数后面
function buildName(firstName: string, lastName?: string)
默认参数
我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined
时。
function buildName(firstName: string, lastName = "Smith")
带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入
undefined
值来获得默认值。
剩余参数
在JavaScript里,你可以使用 arguments
来访问所有传入的参数。
在TypeScript里,可以把所有参数收集到一个变量里,
function buildName(firstName: string, ...restOfName: string[])
this
使用箭头函数返回值可保存当前this,即使该函数已被赋另一个变量
return () => {}
let deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker: function() {
// NOTE: the line below is now an arrow function, allowing us to capture 'this' right here
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();
此时,在部分配置下ts会报错,它会指出 this.suits[pickedSuit]
里的this
的类型为any
。
修改的方法是,提供一个显式的 this
参数。 this
参数是个假的参数,它出现在参数列表的最前面
createCardPicker: function(this: Deck)
重载
建立重载列表
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
真实的函数体
}
它与JavaScript里的处理流程相似。 它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
泛型
可以使用泛型
来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
使用泛型
function identity<T>(arg: T): T {
return arg;
}
我们给identity添加了类型变量T
。 T
帮助我们捕获用户传入的类型(比如:number
),之后我们就可以使用这个类型。 之后我们再次使用了 T
当做返回值类型。
由此可见,的作用是声明一个类型变量,该变量可在调用函数中给出,也可以由传入的参数自动推断得出。
let output = identity<string>("myString");
let output = identity("myString");
泛型接口
创建一个带有类型变量的函数并在实例化的时候指出具体类型。
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型类
创建一个带有类型变量的类并在实例化的时候指出具体类型。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let stringNumeric = new GenericNumber<string>();
let myGenericNumber = new GenericNumber<number>();
泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
枚举
数字枚举
enum Direction {
Up = 1,
Down,
Left,
Right
}
Direction.Down=2;
反向映射
数字枚举成员还具有了 反向映射,从枚举值到枚举名字。
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
当所有枚举成员都拥有字面量枚举值时,
首先,枚举成员成为了类型,这代表枚举成员可以在接口中使用,将某个数据限定为固定对应的枚举成员。
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square,
// ~~~~~~~~~~~~~~~~ Error!
radius: 100,
}
参数枚举
枚举可以作为普通对象传入函数。
function f(obj: { X: number }) {
return obj.X;
}
// Works, since 'E' has a property named 'X' which is a number.
f(E);