跨平台:TypeScript 编译器可以安装在任何操作系统上,包括 Windows、macOS 和 Linux。
ES6 特性:TypeScript 包含计划中的 ECMAScript 2015 (ES6) 的大部分特性,例如箭头函数。
面向对象的语言:TypeScript 提供所有标准的 OOP 功能,如类、接口和模块。
静态类型检查:TypeScript 使用静态类型并帮助在编译时进行类型检查。因此,你可以在编写代码时发现编译时错误,而无需运行脚本。
可选的静态类型:如果你习惯了 JavaScript 的动态类型,TypeScript 还允许可选的静态类型。
DOM 操作:您可以使用 TypeScript 来操作 DOM 以添加或删除客户端网页元素。
增强代码的可读性和可维护性,强类型的系统相当于最好的文档,在编译时即可发现大部分的错误,增强编辑器的功能。
(2)包容性,js文件可以直接改成 ts 文件,不定义类型可自动推论类型,可以定义几乎一切类型,ts 编译报错时也可以生成 js 文件,兼容第三方库,即使不是用ts编写的
(3)有活跃的社区,大多数的第三方库都可提供给 ts 的类型定义文件,完全支持 es6 规范
使用 TS 的缺点:
(1)增加学习成本,需要理解接口(Interfaces)和泛型(Generics),类(class),枚举类型(Enums)
(2)短期增加开发成本,增加类型定义,但减少维护成本
(3)ts 集成到构建流程需要一定的工作量
(4)和有些库结合时不是很完美
TypeScript 里的所有数字都是浮点数。 这些浮点数的类型是 number。和 JavaScript 一样,可以使用双引号( ")或单引号(’)表示字符串。布尔值是最基础的数据类型,在 TypeScript 中,使用 boolean 定义布尔值类型。布尔值是最基础的数据类型,在 TypeScript 中,使用 boolean 定义布尔值类型。声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null。在 TypeScript 中,可以使用 null 和 undefined 来定义这两个原始数据类型。与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量。
Typescript 是 JavaScript 的超集,可以被编译成 JavaScript 代码。 用 JavaScript 编写的合法代码,在 TypeScript 中依然有效。Typescript 是纯面向对象的编程语言,包含类和接口的概念。 程序员可以用它来编写面向对象的服务端或客户端程序,并将它们编译成 JavaScript 代码。
TypeScript和 JavaScript的关系
TypeScript 引入了很多面向对象程序设计的特征,包括:
interfaces 接口
classes 类
enumerated types 枚举类型
generics 泛型
modules 模块
主要不同点如下:
TS 是一种面向对象编程语言,而 JS 是一种脚本语言(尽管 JS 是基于对象的)。
TS 支持可选参数, JS 则不支持该特性。
TS 支持静态类型,JS 不支持。
TS 支持接口,JS 不支持接口。
泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。可以把泛型理解为代表类型的参数。
我们希望传入的值是什么类型,返回的值就是什么类型
传入的值可以是任意的类型,这时候就可以用到 泛型
如果使用 any 的话,就失去了类型检查的意义
TypeScript 是面向对象的 JavaScript。而其中的类描述了所创建的对象共同的属性和方法。
传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但这对于熟悉使用面向对象方式的程序员来说有些棘手,因为他们用的是基于类的继承并且对象是从类构建出来的。
从ECMAScript 2015,也就是ECMAScript 6,JavaScript程序将可以使用这种基于类的面向对象方法。在TypeScript里允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。而TypeScript的构造函数用关键字constructor来实现。可以通过this(和java/C#一样代表对象实例的成员访问)关键字来访问当前类体中的属性和方法。
一般情况下,创建一个类后并不能直接的对属性和方法进行引用,必须对类进行实例化,即创建一个对象。TypeScript中用new 关键字创建对象。实例化后通过“.”
来访问属性和方法
联合类型(Union Types)表示取值可以为多种类型中的一种。
格式如下:Type1|Type2|Type3
//例如: var val:string|number; if(typeof val === "string") { console.log(val.length) } else { console.log(val) }
交叉类型:交叉类型是将多个类型合并为一个类型。就是说这个类型的对象同时拥有了多种类型的成员。我们大多是在混入(mixins)或其它不适合典型面向对象模型的地方看到交叉类型的使用。 (在JavaScript里发生这种情况的场合很多!) 下面是如何创建混入的一个简单例子:
function extend<T, U>(first: T, second: U): T & U { let result = <T & U>{}; for (let id in first) { (<any>result)[id] = (<any>first)[id]; } for (let id in second) { if (!result.hasOwnProperty(id)) { (<any>result)[id] = (<any>second)[id]; } } return result; } class Person { constructor(public name: string) { } } interface Loggable { log(): void; } class ConsoleLogger implements Loggable { log() { // ... } } var jim = extend(new Person("Jim"), new ConsoleLogger()); var n = jim.name; jim.log();
(1)语法:值 as 类型
(2)用途:将一个联合类型断言为其中一个类型;将有一个父类断言为更加具体的子类;将任意一个类型断言为any;将any断言为一个具体的类型。
(3)类型断言到的限制
any
any
可以被断言为任何类型但类型之间的断言却是有限制的。若A能兼容B,那么可以将A断言为B,也可以将B断言为A
interface Animal { name:string; } interface Cat { name:string; run():void; } const tom:Cat = { name:"tom", run(){ console.log("running"); } } const animal:Animal = tom;
TS是结构类型系统,类型之间的对比只会比较它们最终的结构,而会忽略它们定义时的关系。所以在上例中,尽管Animal
、Cat
定义时并没有任何关系,但结构上可以理解为Cat
继承于Animal
:
interface Cat extends Animal{ run():void; }
即:Animal
兼容Cat
。此时二者可以互相断言:
function testAnimal(animal:Animal){ return animal as Cat } function testCat(cat:Cat){ return cat as Animal; }
animal as cat
是因为父类可以被断言为子类。cat as animal
是因为子类拥有父类的所有属性和方法,调用也不会出问题。综上所述:
any
any
可以被断言为任何类型前四种情况都是最后一种的特例。