本文基于Typescript中文版handbook整理而成。
Typescript学习系列1-快速上手
1 安装Typescript
有两种主要的方式安装Typescript:通过npm安装,或者通过Visual Studio的TypeScript插件,这里我使用npm安装的方式,对于前端开发人员来书更方便。
使用npm安装typescript:
npm install typescript -g
2 编写第一个Typescript代码
在编辑器中新建一个helloWorld.ts
文件,在其中编写如下代码:
function greeter(person: string): string {
return "Hello, " + person;
}
let user = 'Tom';
console.log(greeter(user));
上面是Typescript代码,对greeter函数中的参数person的类型做了约束,对其返回值类型也做了约束。该代码无法直接通过node helloWorld.ts
执行,因为它不是js,node无法理解其语法。如果你尝试使用node执行,会报出如下的错误:
function greeter(person: string): string {
^
SyntaxError: Unexpected token ':'
at Module._compile (internal/modules/cjs/loader.js:891:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
可以使用tsc
命令将ts代码转换为js代码,在命令行运行tsc helloWorld.ts
,将会在同目录下生成一个helloWorld.js
文件,其中的内容为:
function greeter(person) {
return "Hello, " + person;
}
var user = 'Tom';
console.log(greeter(user));
得到的js代码就能够被node正常识别并执行了。
3 Typescript中的新玩意
3.1 接口
接下来我们开发一个示例应用,使用接口来描述一个拥有firstName和lastName字段的对象。 在TypeScript里,只在两个类型内部的结构兼容那么这两个类型就是兼容的。 这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地使用 implements语句。
interface Person {
firstName: string,
lastName: string
}
function greeter(person: Person): string {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = { firstName: "Jane", lastName: "Frank" }
console.log(greeter(user));
执行tsc helloWorld.ts
后得到如下代码:
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = { firstName: "Jane", lastName: "Frank" };
console.log(greeter(user));
可以看到,js代码中直接去掉了Person这个接口。如果我们将ts代码稍作修改,如将user中的lastName
改为name
:
interface Person {
firstName: string,
lastName: string
}
function greeter(person: Person): string {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = { firstName: "Jane", name: "Frank" }
console.log(greeter(user));
再执行tsc的时候就会报错了:
helloWorld.ts:11:21 - error TS2345: Argument of type '{ firstName: string; name: string; }' is not assignable to parameter of type 'Person'.
Property 'lastName' is missing in type '{ firstName: string; name: string; }' but required in type 'Person'.
11 console.log(greeter(user));
~~~~
helloWorld.ts:3:5
3 lastName: string
~~~~~~~~
'lastName' is declared here.
Found 1 error in helloWorld.ts:11
由此可见,虽然最终转换的js代码中没有了接口的定义,但是在转换的过程中ts代码会自动帮我们根据定义的数据类型核对传入的数据是否正确。
3.2 类
我们再使用类来改写这个例子,我们创建一个Student类,它带有一个构造函数和一些公共字段。 注意类和接口可以一起共作,程序员可以自行决定抽象的级别。
还要注意的是,在构造函数的参数上使用public等同于创建了同名的成员变量。
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("Jane", "M.", "User");
console.log(greeter(user));