Vue 学习笔记(二十九):TypeScript 简单了解

TypeScript 是微软开发的自由和开源的编程语言,JavaScript 的一个超集,支持 ECMAScript 6 标准。设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

顾名思义,就是给JavaScript加上type。TypeScript 通过类型注解提供编译时的静态类型检查。

安装

  • 通过npm npm install -g typescript
  • 安装Visual Studio的TypeScript插件(新版本 Visual Studio 默认已包含)

Hello World

文件扩展名是 .ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student {
fullName: string;
constructor(public firstName, public middleInitial, public lastName) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}

interface Person {
firstName: string;
lastName: string;
}

function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Stan", "noMiddleName", "Zhang");

document.body.innerHTML = greeter(user);

然后,运行 TypeScript 编译器:

1
tsc hello.ts

它将编译生成 js 文件 hello.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Student = /** @class */ (function () {
function Student(firstName, middleInitial, lastName) {
this.firstName = firstName;
this.middleInitial = middleInitial;
this.lastName = lastName;
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
return Student;
}());
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Stan", "noMiddleName", "Zhang");
document.body.innerHTML = greeter(user);

运行,

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title></head>
<body>
<script src="greeter.js"></script>
</body>
</html>

页面输出:Hello, Stan Zhang

还是有点怪怪的,可以看到 document.body.innerHTML = greeter(user); 执行了 greeter(person : Person)函数,它的入参是 Person 接口类型。接口描述了一个拥有firstName和lastName字段的对象。在TypeScript里,只在两个类型内部的结构兼容那么这两个类型就是兼容的。这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地使用 implements语句。

再看 Student 类,它表面上并没有接口要求的firstName、lastName。但是,实际是有的:在构造函数的参数上使用public等同于创建了同名的成员变量。

类的构造函数是constructor

基础类型

TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型。

布尔值

1
let isDone: boolean = false;

数字

和JavaScript一样,TypeScript里的所有数字都是浮点数。 这些浮点数的类型是 number。 除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。

1
2
3
4
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

字符串

JavaScript程序的另一项基本操作是处理网页或服务器端的文本数据。 像其它语言里一样,我们使用 string表示文本数据类型。 和JavaScript一样,可以使用双引号或单引号表示字符串。

1
2
let name: string = "bob";
name = "smith";

还可以使用模版字符串,它可以定义多行文本和内嵌表达式。 这种字符串是被反引号包围( `),并且以${ expr }这种形式嵌入表达式

1
2
3
4
5
let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.

I'll be ${ age + 1 } years old next month.`;

与下面定义sentence的方式效果相同:

1
2
let sentence: string = "Hello, my name is " + name + ".\n\n" +
"I'll be " + (age + 1) + " years old next month.";

数组

有两种方式可以定义数组。
第一种,可以在元素类型后面接上 [],表示由此类型元素组成的一个数组:

1
let list: number[] = [1, 2, 3];

第二种方式是使用数组泛型,Array<元素类型>

1
let list: Array<number> = [1, 2, 3];

元组 Tuple

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。
跟python的元组还是有区别的

1
2
3
4
5
6
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error

用索引访问元素:

1
2
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'

当访问一个越界的元素,会使用联合类型替代:

1
2
3
4
5
x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型

console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toString

x[6] = true; // Error, 布尔不是(string | number)类型

枚举

enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。

1
2
enum Color {Red, Green, Blue}
let c: Color = Color.Green;

默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1开始编号:

1
2
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

或者

1
2
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

使用:

1
2
3
4
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];

console.log(colorName); // 显示'Green'因为上面代码里它的值是2

Any

那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any类型来标记这些变量。

any类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。 你可能认为 Object有相似的作用,就像它在其它语言中那样。 但是 Object类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法,即便它真的有这些方法。

1
2
3
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

当你只知道一部分数据的类型时,any类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:

1
2
3
let list: any[] = [1, true, "free"];

list[1] = 100;

Void

某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:

1
2
3
function warnUser(): void {
console.log("This is my warning message");
}

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

1
let unusable: void = undefined;

Null 和 Undefined

TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大。默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给number类型的变量。

1
2
3
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;