为什么应用Typescript?
微软推出TypeScript次要是为实现两个指标:
- 为Javascript提供可选的类型零碎;
- 兼容以后及将来的JavaScript的个性。
动态类型带来的益处:
- 有利于代码重构,它在编译器编译的时候就能捕捉谬误。
- 类型明确有利于浏览。
JavaScript常见语法
TypeScript是JavaScript的“超集”,typescript将javascript语法标准化。
== 与 ===
应用==进行比拟时,会进行隐式转换。
2 == 2 true2 == '2' true2 === '2' false
援用
除字面量外,JavaScript中的任何对象(包含函数、数组、正则表达式等)都是一个援用。
null和undefined
变量没有初始化:undefined。变量不可用为null。
undefined == undefined trueundefined == null true// 查看变量是否初始化if( typeof val !== 'undefined'){}
this
this关键字指向调用上下文
function foo(){console.log(this)} /** this --> window **/var obj = {foo:function(){console.log(this)}} obj.foo() /** this --> obj */
闭包
外部函数拜访内部变量,此时内部函数的变量被外部函数绑定,称为闭包。
function outer(){ var outerVal = '1' function inner(){ console.log(outerVal) } outer()}/** inner 绑定了 outerVal */
数字
JavaScript中数值是双精度的64位的number
console.log(.1 + .2) // 0.30000000000000004
内置整数类型限度 Number.MAX_SAFE_INTEGER-Number.MIN_SAFE_INTEGER
金融计算中个别应用 big.js
NaN,计算出的后果不是非法数值时返回NaN,检测NaN,Number.isNaN。
- thuthy
!!双感叹号,第一个!是将值转为布尔值,第二个逻辑反转。
ES6语法
class
/*ES6*/class Point { x: number y: number constructor(x: number, y: number) { this.x = x this.y = y } add(point: Point) { return new Point(this.x + point.x, this.y + point.y) }}/*编译后ES5*/var point = function(){ function Point(x, y){ this.x = x; this.y = y; } Point.prototype.add = function(point){ return new Point(this.x + point.x, this.y + point.y) } return Point;}()
继承
/*ES6*/class Point3D extends Point { z: number constructor(x: number, y: number, z: number) { super(x, y) this.z = z } add(point: Point3D) { var point2D = super.add(point) return new Point3D(this.x + point2D.x, this.y + point2D.y, this.z + point.z) }}/*编译后ES5*/var point3D = function(_super){ __extends(Point3D, _super) function Point3D(x, y, z){ _super.call(this, x, y) this.z = z; } Point3D.prototype.add = function(point){ var point2D = _super.prototype.add.call(this, point) return new Point3D(this.x + point2D.x, this.y + point2D.y, this.z + point.z) } return Point;}(Point)/**__extends typescript 编译 extends 时生成*/var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };/*d示意派生类,b示意基类*/ return function (d, b) { extendStatics(d, b); // 拷贝动态变量 function __() { this.constructor = d; } // 保留派生结构器 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); //d.prototype.__proto__ = b.prototype };})();
辨别 proto prototype
javascript 中所有对象都有属性__ proto __
/** 查找属性程序 obj.propertyobj.__proto__.propertyobj.__proto__.__proto__.property**/
javasript 所有的函数都有属性 prototype,prototype有个指向函数自身的结构器constructor。
function Foo(){ this.name = "xm"}var foo = new Foo();/**通过函数创立的对象,会将函数prototype传给对象__proto__*/console.log(foo.__proto__ === Foo.prototype)
箭头函数
var inc = x => x + 1;
箭头函数带来语法简洁和this失落问题。
rest参数
...+参数名的模式示意最初一个参数,获取时转为数组。
let和const
var 变量是函数作用域,let 变量块作用域
/**闭包中的var*/var funcs = []for(var i = 0;i < 3; i++){ funcs.push(function(){ console.log(i) })}for(var j = 0;j < 3; j++){ funcs[j]();}/*输入 3*/
const 申明常量值。
解构
反对对象和数组解构。
/*对象解构*/var person = {name:'x',age:12,gender:1}var {name, age} = personconsole.log(name, age) // x, 12var {x, y, ...remaining} = {x: 1, y: 2, z: 4, w: 5} // 看作删除了x,yconsole.log(x,y,remaining) // 1,2 {z:4,w:5}
扩大运算符
Function.prototype.apply
/*apply调用*/function foo(x,y){}var args = [0,1]foo.apply(null, args)// 新语法foo(...args)// 数组追加元素var list = [1, 2]list = [...list, 3] // [1,2,3]list = [0,...list,4] // [0,1,2,3,4]
for...of
/*for...in*/for(var e in [7,8,9]){console.log(e) }// 返回索引for(var e of [7,8,9]){console.log(e) }// 返回元素
Promise
应用Promise解决异步和回调函数。
var promise = new Promise((resolve, reject) => {resolve()//回调正确值 reject() // 异样值 })promise.then(res => {}) // 失常.catch(err => {}) // 异样
并行流程管制,Promise.all([promise1,promise2]).then(res => [result1, result2])
generators
function* idGen(){ let index = 0 while(index < 3) yield /*暂停*/ index++;}var id = idGen();console.log(id.next());console.log(id.next());console.log(id.next());console.log(id.next());
async/await
async function foo(){ var result = await exPromise() //期待promise执行返回 console.log(result)}
TS我的项目形成
编译上下文
tsconfig.json配置文件,配置选项:tsconfig
申明空间
类型申明空间和变量申明空间。
- 类 (class): 类型, 值.
- 接口 (interface): 类型.
- 枚举 (enum): 类型, 值.
- 类别名 (type): 类型.
- 函数 (function): 值.
- 变量 (let, const, var, parameters): 值.
模块
默认状况下申明处于全局命名空间中。应用export变成文件模块。
模块门路查找
/**相对路径**/import * as foo from './foo' // 同级目录import * as foo from '../foo' // 下级目录import * as foo from '../someFolder/foo // 绝对目录/**导入门路不是相对路径时,动静查找**/import * as foo from 'foo'/*查找程序./node_modules/foo../node_modules/foo../../node_modules/foo*/import * as foo from 'something/foo'/**./node_modules/something/foo../node_modules/something/foo../../node_modules/something/foo*//* place */import * as foo from 'foo'/**查找程序*//**foo 是文件 foo.tsfoo 是目录 foo/index.tsfoo 是目录 foo/package.json 有 typesfoo 是目录 foo/package.json 有 main**/
命名空间
//typescript 申明namespace Utility { export function log(msg) { console.log(msg); } export function error(msg) { console.log(msg); }}// usageUtility.log('Call me');Utility.error('maybe');
var Utility;(function (Utility) { function log(msg) { console.log(msg); } Utility.log = log; function error(msg) { console.log(msg); } Utility.error = error;})(Utility || (Utility = {}));// usageUtility.log('Call me');Utility.error('maybe');
动静导入表达式
// 动静加载import(/* webpackChunkName: "momentjs" */ 'moment') .then(moment => { // 懒加载的模块领有所有的类型,并且可能按期工作 const time = moment().format(); console.log('TypeScript >= 2.4.0 Dynamic Import Expression:'); console.log(time); }) .catch(err => { console.log('Failed to load moment', err); });
创立TS我的项目
- 装置node环境,创立目录进入执行 npm init -y;
- 装置ts npm install typescript --save-dev ;
- 创立文件 node.d.ts npm install @types/node --save-dev;
- 初始化tsconfig.json npx tsc --init --rootDir src --outDir lib --esModuleInterop --resolveJsonModule --lib es6 , dom --module commonjs;
- 增加ts-node:npm install ts-node --save-dev 实现实时编译和运行;
- 增加nodemon:npm install nodemon --save-dev,只有文件被扭转,它就会调用ts-node。
TS类型零碎
基本概念
根本类型 number string boolean string[]
接口 interface
非凡类型 any、null、undefined和void
// 接口interface Name{ first: string, last: string};let n : Name;n = { first: 'Li', last:'p'}// 泛型function contact<T>(items : T[]): T[]{ //...... return items;}// 联结类型function join(items : string[] | string){ //......}// 穿插类型function extend<T, U>(first: T, last : U) :T & U{ const result = <T & U>{} return result}// 元祖类型let nameNum : [string, number]//类型别名type mind = string | Numberlet m : mind
@types
仓库 @types 通过配置tsconfig.json的compilerOptions.types管制全局。
环境申明
应用关键字declare进行申明,个别放在.d.ts文件。
枚举
数字枚举和字符串枚举。
lib.d.ts
装置TypeScript时,会顺带装置一个lib.d.ts申明文件。这个文件蕴含JavaScript运行时及DOM(Document Object Model,文档对象模型)中存在的各种常见的JavaScript环境申明。
函数
申明函数 type inc = (num : number) => number
可调用可实例化
// 可调用interface ReturnStr{ () : string;}declare const foo : ReturnStrconst str = foo() // str 字符串// 内联注解const overload: { (foo: string): string; (foo: number): number;} = (foo: any) => foo// 可实例化interface NewAble { new (): string;}declare const newAble: NewAble;const foo = new newAble
类型断言
Ts能够以任何形式去重写其推断和剖析的类型,称为类型断言。
interface Foo{ Bar : string}const f1 = {} as Foo;f1.bar = "1";const f2 = <Foo>{};f2.bar = "2";
Freshness
查看字面量类型
function hasName(some: { name: string }) { some.name = "name"; // 正确 some.age = 12; // 谬误}
类型爱护
typeof (typeof x === 'string')
instanceof (foo instanceof Foo)
in 查看对象是否存在对应属性
readonly
type Foo = { readonly bar: string;};const f: Foo = { bar: "x" };f.bar = "y"; // 谬误,不可批改
泛型
类的实例成员、类的办法、函数的参数、函数返回值之间的束缚。
never
never类型就是TypeScript中的底部类型。用于一个总会抛出谬误的函数或一个总会抛出谬误的函数。
never与void的差别,void示意没有任何类型,never示意永远不存在的值的类型。
异样解决
try { throw new Error("err.");} catch (error) { console.log(error)}
代码格调约定
- 应用camelCase模式为变量和函数命名。
- 应用PascalCase模式为类命名。
- 应用PascalCase模式为接口命名。
- 类型别名应用PascalCase模式进行命名。
- 命名空间应用PascalCase模式进行命名。
- 枚举类型应用PascalCase模式进行命名。
- 对于须要明确表明不可用的状况,null和undefined都不倡议应用。
格式化
tsfmt命令格式化,应用单引号,空格两tab,如果想用extends或implements,则倡议应用interface。
TS编译原理
.....待续再看