TypeScript学习笔记一:简介(译)
TypeScript简介
TypeScript(以下简称ts)是由微软开发的自由和开源的编程语言,它是为满足建立和维护大型的js程序而设计的,它能帮助开发团队定义软件组件之间的接口,深入了解已存在的js库。ts可通过把代码组织到可动态加载的模块中来降低命名冲突。ts的可选类型系统可帮助js程序员使用静态检测、基于符号导航、语句完成和代码重构等高效开发工具实现快速编码
ts是js的语法糖。它是ECMAScript 2015的一个超集。每一个js程序也是一个ts程序。ts编译器只将本地文件转换为ts程序而不对已声明的变量重新排序,这保证了js输出与ts输入紧密匹配。ts不改变变量名,能直接调试生成的js代码。ts提供了可选的源码映射以实现源码级调试。ts工具时在文件保存,保存测试,编辑时生成js代码。
ts的语法包含ECMAScript 2015的所有特性,包括类和模块,并且兼容ECMAScript 3和ECMAScript 5。
类使我们可以用标准的方式来表达普通的面向对象模式,这让诸如继承等特性更具可读性和可互操作性。我们可以用模块(Module)来组织代码到组件当中以避免命名冲突。ts编译器提供模块代码生成选项以支持静态或动态模块内容加载。 ts还提供了一个可选的类型注释系统。这些类型注释类似于闭包系统当中的JsDoc注释,但不同的是,ts直接将其集成到语法中。这种集成使代码更具可读性,并降低了变量与相应类型注释同步的成本。ts的类型系统使用了类型推断。例如, ts可以从下面的语句推断出变量“i“的类型为”number“类型。
var i=0;
同样地,ts将从下面的函数定义中推断出函数“f”的返回类型为“string”类型。此例我们并未提供类型注释。
function f() {
return "hello";
}
代码编辑器可以利用ts的类型推断服务来找到字符串对象的成员,如下面的屏幕截图。在ts中,我们可以使用下面的方式来表示参数的类型
function f(s:string){
return s;
}
f({}); //error,参数类型不匹配
f('hello'); //ok
这种可选的参数类型注释使ts类型检查器知道我们所期望的参数"s"的类型是"string类型。在函数f的函数体中,工具可以假设s的类型为string类型,然后通过运算符类型检查提供和与此假设相一致的成员。此例,ts编译器将生成下面的js代码:
function f(s) {
return s;
}
我们可以看到,输出的 js代码的所有类型的注释已被擦除。
1.1 环境声明(Ambient)
环境变量声明将变量引入ts域(scope),但不影响已经生成的JavaScript程序。我们可以使用环境声明告诉ts编译器某个组件将提供一个变量。默认情况下,ts编译器在使用未定义变量是会提示错误。 我们可以使用环境声明来添加一些常用的浏览器变量定义。 下面的示例声明了浏览器提供的“document”对象。 因为声明没有指定类型,因此推断该类型为“any”。类型“any”意味着工具可以对文档对象的形状或行为不做任何假设。 下面的一些例子将说明如何使用类型来进一步描述对象的预期行为。
declare var document; document.title = "Hello";
ts编辑器没有包含JQuery接口,因此如果要使用jquery,就得提供一个声明:
declare var $;
1.2 函数类型(Function Type)
js中的函数表达式通过函数定义来创建闭包:此类函数从定义的范围中捕获信息。闭包是目前js的唯一数据封装方法。 通过获取和使用环境变量,闭包内的信息将不能被闭包外的成员访问。js程序员通常用闭包来表示事件处理和异步回调,ts函数类型使我们可以表达所期望的函数签名。函数签名包含参数类型序列和一个返回类型。下面的例子用函数类型来表示一个异步投票系统所需的回调签名。function vote(candidate: string, callback: (result: string) => any) {
// ...
}
vote("BigPig", function(result: string) {
if (result === "BigPig") {
// ...
}
} );
(result: string) => any
1.3 对象类型(Object Type)
我们可以用对象类型来声明期望的对象行为。下面的例子中"MakePoint"变量的类型为“function”类型,此函数的返回值为对象类型。var MakePoint: () => { x: number; y: number; };
interface Friend {
name: string;
favoriteColor?: string;
}
function add(friend: Friend) {
var name = friend.name;
}
add({ name: "Fred" }); // Ok
add({ favoriteColor: "blue" }); // Error, name缺失
add({ name: "Jill", favoriteColor: "green" }); // ok
interface JQuery {
text(content: string);
}
interface JQueryStatic {
get(url: string, callback: (data: string) => any);
(query: string): JQuery;
}
declare var $: JQueryStatic;
$.get("http://mysite.org/divContent",
function (data: string) {
$("div").text(data);
} );
(query: string): JQuery;
var f: { (): string; };
var sameType: () => string = f;// Ok
var nope: () => number = sameType; // Error: 类型不匹配
(ready: () => any): any;
1.4结构分型(Structural Subtyping)
对象类型的比较是结构比较。例如下面的例子,类“CPoint”与接口“Point”相匹配,因为"CPoint"包含"Point"全部的成员。一个类可以可选的声明实现一个接口,编译器将检测声明是否结构兼容。interface Point {
x: number; y: number;
}
function getX(p: Point) {
return p.x;
}
class CPoint {
x: number; y: number;
constructor(x: number, y: number) {
this.x = x; this.y = y;
}
}
getX(new CPoint(0, 0)); // Ok
getX({ x: 0, y: 0, color: "red" }); //ok
getX({ x: 0 }); // Error: 参数不匹配
1.5 上下文类型(Contextual Typing)
function mul(a: number, b: number) {
return a * b;
}
$.get("http://mysite.org/divContent",
function (data) {
$("div").text(data); // ts推断data类型为“string”
} );
1.6 类(Classes)
class BankAccount {
balance = 0;
deposit(credit: number) {
this.balance += credit;
return this.balance;
} }
var BankAccount = (function () { function BankAccount() {
this.balance = 0;
}
BankAccount.prototype.deposit = function(credit) {
this.balance += credit;
return this.balance;
};
return BankAccount;
})();
interface BankAccount {
balance: number;
deposit(credit: number): number;
}
var BankAccount: new() => BankAccount;
class BankAccount { balance: number; constructor(initially: number) { this.balance = initially; } deposit(credit: number) { this.balance += credit; return this.balance; } }
class BankAccount { constructor(public balance: number) { } deposit(credit: number) { this.balance += credit; return this.balance; } }
class CheckingAccount extends BankAccount { constructor(balance: number) { super(balance); } writeCheck(debit: number) { this.balance -= debit; } }
1.7 枚举类型(Enum Types)
const enum Operator {
ADD, DIV, MUL, SUB
}
function compute(op: Operator, a: number, b: number) {
console.log("the operator is" + Operator[op]); // ...
}
此例中,”Operator“声明为枚举成员列表自动分配一个以零开始的整型值。枚举声明也可以为枚举成员显示指定整型值。
当枚举声明被”const"修饰符修饰时,ts编译器为枚举成员生成的js代码是枚举成员的值。如下“compute"函数:switch (op) {
case Operator.ADD:
// execute add
break;
case Operator.DIV:
// execute div
break; // ...
}
生成的js代码如下:
switch (op) {
case 0 /* Operator.ADD */:
// execute add
break;
case 1 /* Operator.DIV */:
// execute div
break; // ...
}

浙公网安备 33010602011771号