2 基础(下) – TS系列教程

函数的类型

函数声明

function sum(x: number, y: number): number {
    return x + y;
}
sum(1, 2, 3); // 报错:输入多余的(或者少于要求的)参数,是不被允许的:

 

函数表达式

let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};

 

使用接口定义函数

interface SearchFunc {
(source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}

 

使用?来定义可选参数,注意可选参数必须靠后

function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}

 

使用…来获取剩余参数

function push(array: any[], ...items: any[]) {
items.forEach(function(item) {
array.push(item);
});
}

 

重载

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

function reverse(x: number): number;
function reverse(x: string): string;

function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}

 

类型断言

类型断言(Type Assertion)可以用来手动指定一个值的类型。
值 as 类型

将一个父类断言为更加具体的子类

class ApiError extends Error {
code: number = 0;
}
class HttpError extends Error {
statusCode: number = 200;
}

function isApiError(error: Error) {
if (typeof (error as ApiError).code === 'number') { //有点类似error instanceof ApiError
return true;
}
return false;
}

 

声明文件

当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。

declare var jQuery: (selector: string) => any; //如果不声明全局变量,直接使用JQuery会报错

jQuery('#foo');

 

通常我们会把声明语句放到一个单独的文件(jQuery.d.ts)中,这就是声明文件3:

// src/jQuery.d.ts
declare var jQuery: (selector: string) => any;

// src/index.ts
jQuery('#foo');

 

使用 @types安装已有的第三方声明文件

npm install @types/jquery --save-dev

 

Node.js 不是内置对象的一部分,如果想用 TypeScript 写 Node.js,则需要引入第三方声明文件:

npm install @types/node --save-dev

 

2 基础(上) – TS系列教程

原始数据类型

JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。

let isDone: boolean = false;
let decLiteral: number = 6;
let myName: string = 'Tom';
let unusable: void = undefined;
let u: undefined = undefined;
let n: null = null;

 

undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:
// 非严格模式下这样不会报错 “strict”: false,
let num: number = undefined;

任意值

如果变量声明的时候未指定类型,则默认为任意值类型

let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;
let something;
something = 'seven';
something = 7;

 

类型推论

let myFavoriteNumber = 'seven'; //ts会根据第一次赋值的变量类型来指定类型,所以myFavoriteNumber的类型会被指定为字符串
myFavoriteNumber = 7; //这样会报错

 

联合类型

let myFavoriteNumber: string | number; //可以同时设置多种类型
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

 

对象的类型——接口

interface Person {
name: string;
age: number;
}

let tom: Person = {
name: 'Tom',
age: 25
};

 

定义的变量比接口少或多了一些属性都是不允许的:

interface Person {
name: string;
age: number;
}
// 少了会报错
let tom: Person = {
name: 'Tom'
};
// 多了会报错
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
// Property 'age' is missing in type '{ name: string; }'.

 

 

有时我们希望不要完全匹配一个形状,那么可以用可选属性:

interface Person {
name: string;
age?: number;
}

let tom: Person = {
name: 'Tom'
};

 

有时候我们希望一个接口允许有任意的属性,使用 [propName: string] 定义了任意属性(name,age)取 string 类型的值。

interface Person {
name: string;
age?: number;
[propName: string]: any; // 注意这里如果定义为字符串的话则会报错,以为和上面的age定义为number冲突
}

let tom: Person = {
name: 'Tom',
gender: 'male'
};

只读属性
interface Person {
readonly id: number; // 后期不可改变类型
name: string;
age?: number;
[propName: string]: any;
}

 

数组的类型

let fibonacci: number[] = [1, 1, 2, 3, 5];
let fibonacci: number[] = [1, '1', 2, 3, 5]; //number数组如果里面有字符串类型,会报错
let fibonacci: Array = [1, 1, 2, 3, 5]; //泛型,后面会详细讲
let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }]; //任意类型的数组
//接口的方式定义数组
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
// 类数组
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}

 

1 简介 – TS系列教程

TypeScript 顾名思义,“类型”是其最核心的特性。

TypeScript 是静态类型,因为ts文件在编译成js文件的过程中进行检查,而JavaScript没有编译阶段,运行的时候才会进行检查,所以会在运行阶段报错,而TS在编译阶段就会发现问题。

TypeScript 是弱类型,1 + ‘1’不会报错。例如Python 是强类型,需要改成str(1) + ‘1’才能通过。

TypeScript 拥有很多编译选项,类型检查的严格程度由你决定

安装方式,建议全局安装,省去一些麻烦。

npm install -g typescript

新建一个a.ts,代码如下:

function sayHello(person: string) {
return 'Hello, ' + person;
}

let user = 'Tom';
console.log(sayHello(user));

 

然后在控制台执行

tsc --init 生成tsconfig.json配置文件,不然编辑器的代码会乱报错
tsc a.ts 生成a.js