什么是 TypeScript

TypeScript 是微软开发的 JavaScript 的超集,TypeScript兼容JavaScript,可以载入JavaScript代码然后运行。TypeScript与JavaScript相比进步的地方 包括:加入注释,让编译器理解所支持的对象和函数,编译器会移除注释,不会增加开销;增加一个完整的类结构,使之更新是传统的面向对象语言。

TypeScript 优势

TypeScript 主要特点包括:

  • TypeScript 是微软推出的开源语言,使用 Apache 授权协议
  • TypeScript 是 JavaScript 的超集
  • TypeScript 增加了可选类型、类和模块
  • TypeScript 可编译成可读的、标准的 JavaScript
  • TypeScript 支持开发大规模 JavaScript 应用
  • TypeScript 设计用于开发大型应用,并保证编译后的 JavaScript 代码兼容性
  • TypeScript 扩展了 JavaScript 的语法,因此已有的 JavaScript 代码可直接与 TypeScript 一起运行无需更改
  • TypeScript 文件扩展名是 ts,而 TypeScript 编译器会编译成 js 文件
  • TypeScript 语法与 JScript .NET 相同
  • TypeScript 易学易于理解

JavaScript 与 TypeScript 的区别

  • TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。
  • TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。
  • TypeScript 增加了代码的可读性和可维护性
    类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了,可以在编译阶段就发现大部分错误,这总比在运行时候出错好,增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等。
  • TypeScript 非常包容
    TypeScript 是 JavaScript 的超集,.js 文件可以直接重命名为 .ts
    即可,即使不显式的定义类型,也能够自动做出类型推论,可以定义从简单到复杂的一切类型,即使 TypeScript 编译报错,也可以生成
    JavaScript 文件,兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript
    读取。

TypeScript 对JavaScript的改进主要是静态类型检查

  1. 静态类型检查可以做到early

    fail,即你编写的代码即使没有被执行到,一旦你编写代码时发生类型不匹配,语言在编译阶段(解释执行也一样,可以在运行前)即可发现。针对大型应用,测试调试分支覆盖困难,很多代码并不一定能够在所有条件下执行到。而假如你的代码简单到任何改动都可以从UI体现出来,这确实跟大型应用搭不上关系,那么静态类型检查确实没什么作用。

  2. 静态类型对阅读代码是友好的,比如我们举个例子
    jQuery API Documentation
    这是大家都非常喜欢用的jQuery.ajax,在这份文档中,详尽地解释了类型为object的唯一一个参数settings,它是如此之复杂,如果没有文档,我们只看这个函数声明的话,根本不可能有人把这个用法猜对。针对大型应用,方法众多,调用关系复杂,不可能每个函数都有人编写细致的文档,所以静态类型就是非常重要的提示和约束。而假如你的代码像jQuery这样所有函数基本全是API,根本没什么内部函数,而且逻辑关系看起来显而易见,这确实跟大型应用搭不上关系,那么静态类型对阅读代码确实也没什么帮助。总的来说,现代编程语言设计,很多特性已经有非常成熟的理论支持了,如果我们重视计算机基础,那么一些语言的适用场景就像是拼积木,可以用几句话概括。像是TS对JS这样,只是单一特性变化。

TypeScript 的缺点

  • 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的东西
  • 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
  • 集成到构建流程需要一些工作量
  • 可能和一些库结合的不是很完美

如何使用

安装Typescript
npm install -g typescript
编译.ts文件-->javescript
编译 tsc xxx.ts
实时编译 tsc xxx.ts -w

语法简介

类型

js原始数据类型包括:布尔值、数值、字符串、null、undefined
在js基础上新加了any,void类型

在 TypeScirpt 中,可以用 void 表示没有任何返回值的函数
声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null
undefined 和 null 是所有类型的子类型

如果是 any 类型,则允许被赋值为任意类型
声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型
如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型

如果是一个普通类型,在赋值过程中改变类型是不被允许的

对象的类型——接口

在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implements)
赋值的时候,变量的形状必须和接口的形状保持一致
未定义任意属性时,多些、少些属性都是不被允许的
一旦定义了任意属性,那么确定属性和可选属性都必须是它的子属性
只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候

interface Person {
readonly id: number; // 只读属性
name: string; // 确定属性
age?: number; // 可选属性
[propName: string]: any; // 任意属性
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};

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

function sum(x: number, y: number): number {
return x + y;
}

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

interface SearchFunc {
(source: string, subString: string): boolean;
} let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
// 编译前
function buildName(firstName: string, lastName?: string) {
return lastName ? firstName + ' ' + lastName : firstName
}
// 编译后
function buildName(firstName, lastName) {
return lastName ? firstName + ' ' + lastName : firstName;
}

输入多余的(或者少于要求的)参数,是不被允许的
可选参数后面不允许再出现必须参数
TypeScript 会将添加了默认值的参数识别为可选参数

剩余参数

// 编译前
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
});
}
// 编译后
function push(array) {
var items = [];
for (var _i = 1; _i < arguments.length; _i++) {
items[_i - 1] = arguments[_i];
}
items.forEach(function (item) {
array.push(item);
});
}

元组

数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同
let xcatliu: [string, number] = ['Xcat Liu', 25];
当赋值给越界的元素时,它类型会被限制为元组中每个类型的联合类型:

let xcatliu: [string, number];
xcatliu = ['Xcat Liu', 25, 'http://xcatliu.com/'];

枚举

枚举(Enum)类型用于取值被限定在一定范围内的场景

枚举使用 enum 关键字来定义
枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射
一个枚举类型可以包含零个或多个枚举成员。 枚举成员具有一个数字值,它可以是 常数或是计算得出的值
enum Color {Red, Green, Blue = "blue".length};

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
// 编译后
var Days;
(function (Days) {
Days[Days["Sun"] = 0] = "Sun";
Days[Days["Mon"] = 1] = "Mon";
Days[Days["Tue"] = 2] = "Tue";
Days[Days["Wed"] = 3] = "Wed";
Days[Days["Thu"] = 4] = "Thu";
Days[Days["Fri"] = 5] = "Fri";
Days[Days["Sat"] = 6] = "Sat";
})(Days || (Days = {}));
// Days --> { '0': 'Sun', '1': 'Mon', '2': 'Tue', '3': 'Wed', '4': 'Thu', '5': 'Fri', '6': 'Sat', Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }

给枚举项手动赋值: enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点的

当满足以下条件时,枚举成员被当作是常数:

  • 不具有初始化函数并且之前的枚举成员是常数。在这种情况下,当前枚举成员的值为上一个枚举成员的值加 1。但第一个枚举元素是个例外。如果它没有初始化方法,那么它的初始值为 0
  • 枚举成员使用常数枚举表达式初始化。常数枚举表达式是 TypeScript 表达式的子集,它可以在编译阶段求值

当一个表达式满足下面条件之一时,它就是一个常数枚举表达式:

  • 数字字面量
  • 引用之前定义的常数枚举成员(可以是在不同的枚举类型中定义的)如果这个成员是在同一个枚举类型中定义的,可以使用非限定名来引用
  • 带括号的常数枚举表达式
  • +, -, ~ 一元运算符应用于常数枚举表达式
  • +, -, *, /, %, <<, >>, >>>, &, |, ^ 二元运算符,常数枚举表达式做为其一个操作对象。若常数枚举表达式求值后为NaN或Infinity,则会在编译阶段报错

所有其它情况的枚举成员被当作是需要计算得出的值

泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性

function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法

interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}

也可以使用含有泛型的接口来定义函数的形状:

interface CreateArrayFunc {
<T>(length: number, value: T): Array<T>;
}
let createArray: CreateArrayFunc;
createArray = function<T>(length: number, value: T): Array<T> {
let result = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}

TypeScript 除了实现了所有 ES6 中的类的功能以外,还添加了一些新的用法

TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

abstract 用于定义抽象类和其中的抽象方法

编译前
abstract class Animal {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
} class Cat extends Animal {
public sayHi() {
console.log(`Meow, My name is ${this.name}`);
}
} let cat = new Cat('Tom'); 编译后
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Animal = (function () {
function Animal(name) {
this.name = name;
}
return Animal;
}());
var Cat = (function (_super) {
__extends(Cat, _super);
function Cat() {
_super.apply(this, arguments);
}
Cat.prototype.sayHi = function () {
console.log('Meow, My name is ' + this.name);
};
return Cat;
}(Animal));
var cat = new Cat('Tom');

更多阅读资料

Typescript 基础应用的更多相关文章

  1. TypeScript基础以及在Vue中的应用

    TypeScript推出已经很长时间了,在Angular项目中开发比较普遍,随着Vue 3.0的即将推出,TypeScript在Vue项目中使用也即将成为很大的趋势,笔者也是最近才开始研究如何在Vue ...

  2. Typescript基础类型

    1.布尔值__boolean 2.数字__number----除了支持十进制和十六进制字面量,Typescript还支持ECMAScript 2015中引入的二进制和八进制字面量. 3.字符串__st ...

  3. TypeScript基础数据类型

    Typescript与Javascript 二者的区别 作为前端开发的基础语言javascript已经深入人心,人人皆知.作为变成入门的最简单语言,Javascript语言以动态.弱类型语言而著名,学 ...

  4. TypeScript 基础知识点整理

    一.TypeScript的特点 1.支持ES6规范 2.强大的IDE支持(集成开发环境) 允许为变量指定类型,减少你在开发阶段犯错误的几率. 语法提示,在IDE编写代码时,它会根据你所处的上下文把你能 ...

  5. TypeScript基础类型,类实例和函数类型声明

    TypeScript(TS)是微软研发的编程语言,是JavaScript的超集,也就是在JavaScript的基础上添加了一些特性.其中之一就是类型声明. 一.基础类型 TS的基础类型有 Boolea ...

  6. TypeScript 基础入门(一)

    1.TypeScript是什么? TypeScript 是 JavaScript 的一个超集,TypeScript 在 JavaScript 的基础上添加了可选的 静态类型 和基于 类 的面向对象编程 ...

  7. TypeScript基础学习

    什么是TypeScript? TypeScript是一种由微软开发的自由的和开源的编程语言,它是JavaScript的一个超集,扩展了JavaScript的语法. TypeScript支持任意浏览器, ...

  8. Typescript 基础知识

    Typescript 就是 Javascript 的超集,所以首先你要知道 Javascript 基础知识 类型注解 类型注解在TypeScript中是记录函数或变量约束的简便方法. // 布尔值 l ...

  9. Typescript基础(1)——数据类型

    前言 这是开始学习Typescript的一些笔记,涉及的都是很基础的知识点.大神们请绕路或者欢迎指点.今天开始第一部分数据类型的学习. 数据类型 Typescript中为了使代码编写更加规范,更加易于 ...

随机推荐

  1. Mysql基本命令二

    删除id>10的记录:delete from user where id>10; 设置user表的自增字段起始值为10:alter table user anto_increment=10 ...

  2. 日历插件——laydate.js

    laydate是一款很好用的日历控件,兼容了包括IE6在内的所有主流浏览器,默认有三种皮肤,如需其它皮肤可去官网下载http://www.layui.com/laydate/  一.核心方法:layd ...

  3. python 字典操作方法详解

    字典是一种通过名字或者关键字引用的得数据结构,key 类型需要时被哈希,其键可以是数字.字符串.元组,这种结构类型也称之为映射.字典类型是Python中唯一內建的映射类型. 注意,浮点数比较很不精确, ...

  4. Tomcat+Servlet面试题都在这里

    下面是我整理下来的Servlet知识点:  图上的知识点都可以在我其他的文章内找到相应内容. Tomcat常见面试题 Tomcat的缺省端口是多少,怎么修改 Tomcat的缺省端口是多少,怎么修改 ...

  5. ABP官方文档翻译 2.2 ABP会话

    ABP会话 介绍 关于IAbpSession 注入会话 会话属性 覆盖当前会话值 警告! 用户标示 介绍 如果应用需要登录的话,同样也需要知道当前用户可以执行哪些操作.ABP在展现层提供了会话对象,同 ...

  6. 分离Webpack开发环境与生产环境的配置

    这是Webpack+React系列配置过程记录的第五篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

  7. CentOS7修改SSH远程连接端口

      CentOS7修改SSH远程连接端口              

  8. BZOJ 1176: [Balkan2007]Mokia [CDQ分治]

    题意: 有一个n * n的棋盘,每个格子内有一个数,初始的时候全部为0.现在要求维护两种操作: 1)Add:将格子(x, y)内的数加上A. 2)Query:询问矩阵(x0, y0, x1, y1)内 ...

  9. python函数4种类型及函数生成帮助文档

    Pyouthon中函数参数是引用传递(注意不是值传递). 对于不可变类型,因变量不能修改,所以运算不会影响到变量自身: 而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量. a += a   ...

  10. Supervisor 安装及配置管理uwsgi进程

    Supervisor介绍 Supervisor 允许其用户在UNIX类操作系统上控制多个进程. 块如下: 方便 需要为每个进程实例编写rc.d脚本通常是不方便的. rc.d脚本是进程初始化/自动启动/ ...