从typescript源文件到执行的过程

执行者 步骤 说明
TSC 1. TypeScript Source -> TypeScript AST TSC将ts文件转为TS AST(abstract syntax tree)
TSC 2. AST is checked by typechecker TSC的类型检查器对AST做类型检查
TSC 3. TypeScript AST -> Javascript Source TSC将TS AST转为JS的源代码(可能是ES3/5/6)
JS(浏览器/Node.js) 4. Javascript Source -> Javascript AST JS运行时将JS源码转为JS AST
JS(浏览器/Node.js) 5. Javascript AST -> bytecode JS运行时将JS AST 转为字节码,准备运行
JS(浏览器/Node.js) 6. Bytecode is evaluated by runtime JS运行时运行js字节码

其中1-3步是TSC处理的,4-6步为JS运行时处理,可能是浏览器也可能是Node.js。

从上面步骤可以知道,TSC做类型检查是在将TS AST转为JS源码之前,也就是说从TS AST转为JS源码时,是没有做类型检查的。检查类型时针对TS AST的,即第二步。

也意味着TS的类型系统,强类型的各种机制,仅仅对类型检查有用,对产出的JS无影响,增加类型不会污染JS源文件。

关于tsconfig.json

可以通过 tsc –init 创建tsconfig.json文件,如下:

{
"compilerOptions": {
"target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["es2015"], /* Specify library files to be included in the compilation. */
"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "dist", /* Redirect output structure to the directory. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
}
}

下面主要看几个常用配置:

配置属性 描述
include 告诉TSC在哪里找到ts文件
lib 告诉TSC当前运行时已存在的API,通常包括:ES5的bind,新增数组方法,ES6的新增方法等
module 告诉TSC将ts文件转为那种模块标准的js文件,通常有cmj,cmd,es6等
outDir 告诉TSC将转换后的文件放到哪个目录
strict 告诉TSC是否进行严格的类型检查
target 告诉TSC将ts转换成哪个版本的js,通常有ES3,ES5,ES6等
noImplicitAny 是否允许存在未定义的类型,即隐式类型。TSC不会自己猜测类型
alwaysStrict TSC会在产出的每个js文件中带上use strict语句

关于tslint

可以通过 tslint –init 创建默认的tslint.json文件,如下:

{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {},
"rulesDirectory": []
}

{}类型

当将一个变量设置为{}类型是,意味着此变量的值可以是除了null和undefined之外的任何值。

let a:{} = 1;
let b:{} = Symbol('b');
let c:{} = null; // Type 'null' is not assignable to type '{}'.
let d:{} = undefined; // Type 'undefined' is not assignable to type '{}'.

object类型

当将一个变量设置为object类型时,意味着此变量的值可以是除了字符串,数字,Symbol,null,undefined,布尔值之外的任何值。

let a:object = new Date();
let b:object = function(){};
let c:object = [];
let d:object = new RegExp('');
let e:object = true; // Type 'true' is not assignable to type 'object'.
let f:object = Symbol(); // Type 'symbol' is not assignable to type 'object'.
let g:object = 1; // Type '1' is not assignable to type 'object'.
let h:object = '1'; // Type '"1"' is not assignable to type 'object'.

Object类型

同{}类型。

Value {} object Object
{} Yes Yes Yes
[‘a’] Yes Yes Yes
function(){} Yes Yes Yes
new String(‘a’) Yes Yes Yes
‘a’ Yes No Yes
1 Yes No Yes
Symbol() Yes No Yes
true Yes No Yes
null No No No
undefined No No No

[]类型

当一个变量声明为[]类型时,表示变量的值必须为空数组。如果隐式声明为[],则表示元素的类型为any,即任意类型的值。如:

let a:[] = [];
a = [1]; // Type '[number]' is not assignable to type '[]'.
let b = []; // 隐式声明b为数组,元素类型是any类型
b.push(1);
b.push(null);

Tuples类型

此类型是array的子类型,继承自array类型。Tuples类型的数组必须显式申明其元素的类型,且数组长度不可变。如:

// 声明定长的数组
let arr: [string,number,boolean] = ['a',2,true]; // 二维数组的声明
// 分步解释:
// let data: number[] 表示声明一个元素为数字的数组
// let data: [][] 表示声明一个元素为空数组的数组
// let data: [number, number][] 表示声明一个元素为两个元素的tuples类型的数组,且tuples的两个元素必须都为number类型
// let data: [number, number?][] 表示数组的第二个元素可选
let data: [number, number?][] = [[1,2],[3],[4,5]]; // 声明不定长数组,且指定第一个元素的类型,其他元素类型任意
let data1: [string,...any[]] = ['11','s',32];

枚举类型

枚举类型主要处理两类事务:定义字符串到数字的映射或字符串到字符串的映射。TS会自动将枚举类型的每个成员映射到一个数字,默认是从0开始,也可是是显式定义数字,开始位置自己决定,如:

// 默认从0开始
enum lang {Chinese, English, Russian};
let a = lang.Chinese;
console.log(a, lang.English, lang.Russian); // 0, 1, 2
// 定义从3开始
enum lang {Chinese=3, English, Russian};
let a = lang.Chinese;
console.log(a, lang.English, lang.Russian); // 3, 4, 5
// 自定义或者自动赋值
enum lang {Chinese=3, English=6, Russian};
let a = lang.Chinese;
console.log(a, lang.English, lang.Russian); // 3, 6, 7

看枚举类型被TS转换后的形式,如:

var lang;
(function (lang) {
lang[lang["Chinese"] = 3] = "Chinese";
lang[lang["English"] = 9] = "English";
lang[lang["Russian"] = 10] = "Russian";
})(lang || (lang = {}));
;

我们可以通过数字访问到字符串,通过字符串访问到数字,如:

console.log(lang['English'], lang[lang.English]); // 9 English

readonly修饰符

声明对象的某个属性为readonly

let a: {a:string, readonly b:number} = {a:'2', b:3};
a.b = 4; // Cannot assign to 'b' because it is a read-only property.

声明数组为只读

let as: readonly number[] = [1,2,3];
as.push(2); // Property 'push' does not exist on type 'readonly number[]'.
as.concat(3); // concat函数不会对原数组修改,而是返回新的数组,所以此处合法。 // 还可以这样声明
let arr: ReadonlyArray<string> = ['2'];
arr.push('3'); // Property 'push' does not exist on type 'readonly string[]'.
// 或者
let arr: Readonly<string[]> = ['22'];

声明类的属性为只读。类的只读属性可以在声明的时候赋值,或者构造函数中赋值,其他地方都不允许赋值。如:

class Foo{
readonly bar = 1;
readonly baz:string;
constructor(){
this.baz = 'hello';
}
setBaz(value:string){
this.baz = value; // Cannot assign to 'baz' because it is a read-only property.
}
}
console.log(new Foo().baz);

类型的组合

有时候某个变量的值可能需要取其他类型中的某一个类型,这时可以给此变量的类型设置为这些类型的并集,如:

let prop: string|number = 3;
prop = '3'; // 可以被赋值,因为prop可以为string和number类型中的一个 // 数组里可以是字符串也可以是数字
type StringOrNumber = string|number;
let a: StringOrNumber[] = []; // 或者直接这样:let a: (string|number)[] = [];
a.push(1);
a.push('a');
a.push(true); // 类型错误,不可以有布尔类型 type Cat = {name:string, purrs:boolean};
type Dog = {name:string, barks:boolean, wags:boolean}
type CatOrDogOrBoth = Cat|Dog;
let cat: CatOrDogOrBoth = {name: 'John', purrs: true};
// 类型错误 {name: 'John', barks: false} 不属于Cat和Dog中的任何一个类型
let cat2: CatOrDogOrBoth = {name: 'John', barks: false};
// 类型错误,同上
let cat3: CatOrDogOrBoth = {name: 'John', wags: false};
// 类型错误, 同上
let cat4: CatOrDogOrBoth = {barks: true, wags: false};
// 属于Cat类型,因为没有barks属性,即不是Dog类型,且完全拥有Cat类型定义的所有属性
let cat5: CatOrDogOrBoth = {name: 'John', purrs: true, wags: false};
// 既是Cat类型也是Dog类型
let cat6: CatOrDogOrBoth = {name: 'John', barks: false, wags: false, purrs:false}

Typescript项目注意点和基本类型介绍的更多相关文章

  1. 在 Typescript 2.0 中使用 @types 类型定义

    在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经 ...

  2. 在 Ionic2 TypeScript 项目中导入第三方 JS 库

    原文发表于我的技术博客 本文分享了在Ionic2 TypeScript 项目中导入第三方 JS 库的方法,供参考. 原文发表于我的技术博客 1. Typings 的方式 因在 TypeScript 中 ...

  3. vue + typescript 项目起手式

    https://segmentfault.com/a/1190000011744210 2017-10-27 发布 vue + typescript 项目起手式 javascript vue.js t ...

  4. 在TypeScript项目中进行BDD测试

    在TypeScript项目中进行BDD测试 什么是BDD? BDD(Behavior-Driven Design)是软件团队的一种工作方式,通过以下方式缩小业务人员和技术人员之间的差距: 鼓励跨角色协 ...

  5. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

  6. HTTP协议的8种请求类型介绍

    HTTP协议的8种请求类型介绍 转自:http://www.cnblogs.com/liangxiaofeng/p/5798607.html HTTP协议的8种请求类型介绍 HTTP协议中共定义了八种 ...

  7. Linux文件类型介绍

    文件类型介绍: Linux系统不同于Windows系统,两者文件类型和文件扩展名也有很大的差异.Linux中的文件类型和Linux文件的文件扩展名所代表的意义和Windows系统完全不同.用户一般通过 ...

  8. Solidity教程系列1 - 类型介绍

    现在的Solidity中文文档,要么翻译的太烂,要么太旧,决定重新翻译下,再加上代码事例讲解. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果 ...

  9. 智能合约语言Solidity教程系列2 - 地址类型介绍

    智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...

随机推荐

  1. IDS,IPS,IPD

    什么是IDP - 百度文库https://wenku.baidu.com/view/c500cf35eefdc8d376ee3220.html

  2. odoo开发笔记--一个模块显示两个一级菜单

    场景描述: 在已启动开发的模块中,odoo顶部一级菜单只有一个“会员管理”,需求是:在同一级顶部菜单,增加新菜单“产品管理”.举例如图:       处理方式: 按照odoo的机制,实现这种效果,可以 ...

  3. 本地jar包上传docker容器

    先安装docker的注册服务器: [root@VM_0_7_centos ~]# docker run -d -p : --restart=always --name registry2 regist ...

  4. fiddler 捕捉不到代码发出去的HTTP请求

    检查代码里是不是把代理设置为空了,null. 或是通过.config文件禁用了代理.

  5. python+lego ev3的心得总结 随时更新

    一.连接方面 1.试了蓝牙连接,被电脑防火墙拒绝了很多次,很奇怪,明明都pin码都对上了,然后瞬间被踢开. 2.数据线直连,在一台win7上怎么试也不行,在另一台上自动上windows update上 ...

  6. js:如何获取select选中的值

    我想获取select选中的value,或者text,或者…… 比如这个: <select id="select">    <option value=" ...

  7. web自动化测试笔记(二)

    如何使用selenium工具 上章节介绍了搭建web自动化的环境,这个章节介绍如何使用selenium写自动化脚本. 1.selenium selenium是一个用于web应用程序的测试工具.它可以帮 ...

  8. win10 双网卡设置内网和外网同时访问

    当前环境是内网使用固定ip 用有线连接 外网自动获取使用wifi模块连接wifi cmd窗口下运行route print -4 打印路由信息 首先删除 所有0.0.0.0的路由,也就是默认设置 rou ...

  9. Qt qml调试,qml性能分析和优化工具

    QML语言为qt推出的用于界面编程的语言. 1)如何在qt creator中进行调试qml: 以Qt Creator 4.6.2为例: 在qt creator的debug模式下,可以直接在qml中打断 ...

  10. 【剑指offer】面试题 21. 调整数组顺序使奇数位于偶数前面

    面试题 21. 调整数组顺序使奇数位于偶数前面