从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. 方法名同类名相同如果没有__construct,会被当做构造函数。

    简介本文主要罗列些例子,看看当php类名和函数名重名时,php是如何处理的例子<?php class TestObject{ public $subject; private $message ...

  2. 微信小程序开发:背景图片设置

    本文链接:https://blog.csdn.net/michael_f2008/article/details/86543134开发微信小程序时,不能直接在wxss文件里引用本地图片,运行时会报错: ...

  3. [LINUX] 快速回收连接

    i /etc/sysctl.conf 编辑文件,加入以下内容:net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_r ...

  4. 必备Mysql命令

    文章来源:https://macrozheng.github.io/mall-learning/#/reference/mysql 开发者必备Mysql命令 开发者必备Mysql常用命令,涵盖了数据定 ...

  5. rabbitmq设置消息优先级、队列优先级配置

    1.首先在consume之前声明队列的时候,要加上x-max-priority属性,一般为0-255,大于255出错  -----配置队列优先级 配置成功后rabbitmq显示: 2.在向exchan ...

  6. 切换普通用户报 -bash: fork: retry: No child processes

    ssh 连接普通用户 报这个错误 -bash: fork: retry: No child processes 解决办法: 更改vi /etc/security/limits.d/20-nproc.c ...

  7. IIS中发布FTP支持断点续传

    IIS10中发布FTP默认就是支持断点续传的.

  8. linux echo -e 处理特殊字符

    linux echo -e 处理特殊字符 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:\a 发出警告声:\b 删除前一个字符:\c 最后不加上换行符号:\f 换行但光标仍旧停留 ...

  9. C++中的虚函数以及虚函数表

    一.虚函数的定义 被virtual关键字修饰的成员函数,目的是为了实现多态 ps: 关于多态[接口和实现分离,父类指针指向子类的实例,然后通过父类指针调用子类的成员函数,这样可以让父类指针拥有多种形态 ...

  10. 【转帖】编译-O 选项对性能提升作用

    编译-O 选项对性能提升作用 https://www.cnblogs.com/pigerhan/p/3526889.html GCC -O 选项 这个选项控制所有的优化等级.使用优化选项会使编译过程耗 ...