typeScript基础

定义变量限制类型

1
2
3
4
5
6
7
8
9
let isDone: boolean = false;
let decLiteral: number = 6
let sentence: string = `Hello, my name is ${myName}`
let myFavoriteNumber: any = 'seven'; // 如果是 any 类型,则允许被赋值为任意类型
let myFavoriteNumber: string | number; // 联合类型(Union Types)表示取值可以为多种类型中的一种
let fibonacci: number[] = [1, 1, 2, 3, 5]; // 最简单的方法是使用「类型 + 方括号」来表示数组
let fibonacci: (number | string)[] = [1, '1', 2, 3, 5]; // 添加多个类型
let fibonacci: Array<number> = [1, 1, 2, 3, 5]; // 数组泛型
let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }]; // 一个比较常见的做法是,用 any 表示数组中允许出现任意类型

注意:使用构造函数 Boolean 创造的对象不是布尔值:

1
2
3
let createdByNewBoolean: boolean = new Boolean(1);
// Type 'Boolean' is not assignable to type 'boolean'.
// 'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.

空值

JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数:

1
2
3
function alertName(): void {
alert('My name is Tom');
}

声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null:

1
let unusable: void = undefined;

对象类型–接口

在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。

1
2
3
4
5
6
7
8
9
10
11
// 在定义的变量比接口少了一些属性或多一些属性是不允许的,赋值的时候,变量的形状必须和接口的形状保持一致。
interface Person {
name: string;
age: number;
}

let tom: Person = {
name: 'Tom'
};
// index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
// Property 'age' is missing in type '{ name: string; }'.

可选属性

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

1
2
3
4
5
6
7
8
interface Person {
name: string;
age?: number;
}

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

任意属性

有时候我们希望一个接口允许有任意的属性,可以使用如下方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interface Person {
name: string;
age?: number;
[propName: string]: any;
}

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

// 需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
// 任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了
interface Person {
name: string;
age?: number;
[propName: string]: string;
}

let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
// index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'.
// Index signatures are incompatible.
// Type 'string | number' is not assignable to type 'string'.
// Type 'number' is not assignable to type 'string'.

只读属性

有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}

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

tom.id = 9527;
// index.ts(14,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.

数组类型–接口

虽然接口也可以用来描述数组,但是我们一般不会这么做,因为这种方式比前两种方式复杂多了。不过有一种情况例外,那就是它常用来表示类数组。

1
2
3
4
5
// NumberArray 表示:只要索引的类型是数字时,那么值的类型必须是数字。
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];

类数组

1
2
3
function sum() {
let args: IArguments = arguments;
}

其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:

1
2
3
4
5
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}

函数声明

一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:

1
2
3
4
5
6
7
8
9
function sum(x: number, y: number): number {
return x + y;
}

let mySum = function (x: number, y: number): number {
return x + y;
};
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

可选参数

与接口中的可选属性类似,我们用 ? 表示可选的参数

1
2
3
4
5
6
7
function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}

参数默认值

1
2
3
4
5
function buildName(firstName: string, lastName: string = 'Cat') {
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

定义函数的形状–接口

我们也可以使用接口的方式来定义一个函数需要符合的形状:

1
2
3
4
5
6
7
8
interface SearchFunc {
(source: string, subString: string): boolean;
}

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

类型断言

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

有时候,我们确实需要在还不确定类型的时候就访问其中一个类型的属性或方法,比如:

1
2
3
4
5
6
7
8
9
10
11
function getLength(something: string | number): number {
if (something.length) {
return something.length;
} else {
return something.toString().length;
}
}
// index.ts(2,19): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.
// index.ts(3,26): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.

上例中,获取 something.length 的时候会报错。

此时可以使用类型断言,将 something 断言成 string:

1
2
3
4
5
6
7
function getLength(something: string | number): number {
if ((<string>something).length) {
return (<string>something).length;
} else {
return something.toString().length;
}
}

注意:类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的

内置对象

我们可以在 TypeScript 中将变量定义为这些类型

1
2
3
4
5
6
7
8
9
let b: Boolean = new Boolean(1);
let e: Error = new Error('Error occurred');
let d: Date = new Date();
let r: RegExp = /[a-z]/;
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
// Do something
});

安装typeScript的npm包

1
npm install @types/node --save-dev

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×