typescript 版本备忘录

本文深入讲解TypeScript的高级特性,包括类型别名、交叉类型、联合类型等,并介绍如何使用TypeScript进行严格类型检查,增强代码质量。

原文链接

1.X 版本列表

1.1

包可见性(module visibility) ??? module namespace?

一般用.d.ts描述

1.3

protected修饰符

只允许当前类以及子类拓展使用修饰符指定的field,method

tuple元组

限制长度以及索引对应的类型的数组

1.4

union type(联合类型)

一系列的类型

更严格的泛型
let declaration: let 声明
constdeclaration:const 声明

let andconstare only available when targeting ECMAScript 6 (--target ES6).

编译版本为js Es6时生效

template string

es6模板字符串

type guard:类型守卫

使用typeofinstanceof在运行时检查类型,使得typescript扫描器能够理解当前变量的类型

type alias:类型别名

类型之间相互"赋值"

type PrimitiveArray = Array<string | number | boolean>;
type MyNumber = number;
type NgScope = ng.IScope;
type Callback = () => void;
编译后可擦除的enum

静态编译enum,无论是否需要完全编译

enum Student {
  zgz,
  tqh,
  hyj,
}
/* 编译后 */
var Student;
(function (Student) {
    Student[Student["zgz"] = 0] = "zgz";
    Student[Student["tqh"] = 1] = "tqh";
    Student[Student["hyj"] = 2] = "hyj";
})(Student || (Student = {}));

加上const根据代码块动态编译

const enum Student2 {
  zgz,
  tqh,
  hyj,
}
const xx = Student2.hyj;
if (xx == Student2.hyj) {
  console.log(xx);
}
/* 编译后 */
var xx = 2 /* hyj */;
if (xx == 2 /* hyj */) {
    console.log(xx);
}
-noEmitOnErrorcommandline option

产生错误时是否继续将错误编译的js发射出去(生成文件)

1.5

es6 modules 语法支持
解构赋值语法支持
namespace关键字

namespace关键字的加入主要是用于更好地从行为意识上区分 内置模块(internal modules)和外部模块(external modules)

for…of支持
修饰器支持
对象初始化阶段:增强编译器属性计算能力

before

type NeighborMap = { [name: string]: Node };
type Node = { name: string; neighbors: NeighborMap };
function makeNode(name: string, initialNeighbor: Node): Node {
var neighbors: NeighborMap = {};
neighbors[initialNeighbor.name] = initialNeighbor;
return { name: name, neighbors: neighbors };

after

function makeNode(name: string, initialNeighbor: Node): Node {
  return {
    name: name,
    neighbors: {
      [initialNeighbor.name]: initialNeighbor,
    },
  };
}
ts模板字符串增强
tsconfig配置文件支持

使用条件

  • tsc 后的参数不带有 input 文件
--rootDir

控制根目录,主要用于其他输出的计算如--outDir

--noEmitHelpers

???

--newLine

指定换行符(默认 windows \r\n *nix \n)

--inlineSourceMap

控制是否将 mapsource 内容生成在 独立文件

1.6

加入对jsx语法的检查与转换的支持
as Type Operator
ts支持的两种 jsx模式
  • preserve mode :输出一个jsx文件让其他转换工具做transform(如babel)
  • react mode:直接输出一个包含react相关的js文件
加入交叉类型(intersection type)
  • A & B交叉类型表示A类型与B类型的结构相叠加的一个新类型
联合类型逻辑补充
  • A | B表示只能填入一个A结构或B结构的类型

交叉类型,联合类型案例

interface A {
  a: number;
  age: number;
}
interface B {
  b: string;
}
type AXB = A & B;
type AOB = A | B;
let axb: AXB = {
  // 必须填入A和B所有的结构
  a: 1,
  age: 1,
  b: "1",
};
const aob: AOB = {
  //填入A与B类型其中一种的结构
  a: 1,
  age: 1,
};
let aob2: AOB = {
  //填入A与B类型其中一种的结构
  b: "1",
  a: 1,
};
const a = {
  a: 1,
  age: 2,
  b: "3",
  c: 1,
};
aob2 = a; //不做运行时的类型检查
局部类型声明支持

优先使用局部类型声明

interface T {
  x: string;
}
function f() {
  if (true) {
    interface T {
      x: number;
    }
    let v: T = { x: "1" }; //error
    let w: T = { x: 1 }; //correct
  }
}
class 类声明语法支持
class extends 语法支持
abstract 关键字支持
泛型类型别名支持
type Lazy<T> = T | (() => T);
更严格的对象字面量检查
支持es6 generators语法
实验性地支持async 语法
调整模块解析策略--moduleResolution

从1.6版本开始ts提供两种模块查找策略来解决当转换的target为commonjs

  • 'classic’ - module resolution rules used by pre 1.6 TypeScript compiler
  • ‘node’ - node-like module resolution
interfaceclass 类声明合并
declare class Foo {
  public x: number;
}
interface Foo {
  y: string;
}
function bar(foo: Foo) {
  foo.x = 1; // OK, declared in the class Foo
  foo.y = "1"; // OK, declared in the interface Foo
}
支持is类型守护
function Person() {}
Person.prototype.constructor = Person
function isPerson(p): p is Person {//编写一个类型判断
    if(Object.getPrototypeOf(P).constructor === Person) {
        return true
    }else {
        return false
    }
}
excludeproperty support in tsconfig.json

支持排除对数组中的文件目录 文件进行编译

--initcommand line option

生成tsconfig.json

1.7

支持在compile target 为es6使用async/await
新增--module

支持在使用compile target为es6时使用--module指定输出收的模块类型amd esmodule

{
  "compilerOptions": {
    "module": "amd",
    "target": "es6"
  }
}
增强this的推断

ts在方法调用时会推断xx.method(),xx这一个部分的类型

this写可以用于交叉类型去描述一些功能如:混入模式

interface MyType {
  extend<T>(other: T): this & T;
}
支持es7的幂运算符

编译后为Math.pow()

增强对象类型解构的检查
Support for decorators when targeting ES3

1.8

支持类型参数之间的相互约束
function assign<T extends U, U>(target: T, source: U): T {//这里T extends U就是一种约束
  for (let id in source) {
    target[id] = source[id];
  }
  return target;
}
let x = { a: 1, b: 2, c: 3, d: 4 };
assign(x, { b: 10, d: 20 });
assign(x, { e: 0 }); // Error
控制流程错误分析

流程控制语句中的一个的一些错误判断

  • unrearchable code:没有增加判断条件的 return, throw, break or continue 之后的代码被判断为无法到达。默认打开使用--allowUnreachableCode可以关闭该功能

    function foo(flag: boolean): number {
        if(flag) {
            return 1
        } else {
            throw new Error();
        }
        const name = 'zgz' //由于上面必然执行`return 1`或者 throw new Error
        return 2		   //所以下面const 与 return 被判断为unrearchable code
    }
    
  • unused labels:没有使用的流程控制标签。默认打开,使用--allowUnusedLabels可以关闭该功能

    loop: while (x > 0) {//此处的loop就是这样的一个标签
      // Error: Unused label.
      x++;
    }
    
  • implicit returns:针对js会隐式返回一个undefined的检查。默认关闭,使用--noImplicitReturns可以打开该功能

    function f(x) {
      // Error: Not all code paths return a value.
      if (x) {
        return false;
      }
      // implicitly returns `undefined`
    }
    
  • case clause fall-throughs:针对switch流程控制中的case对应代码块为非空的情况进行检查。默认关闭,使用--noFallthroughCasesInSwitch可以打开该功能

    switch (x % 2) {
      case 0: // Error: Fallthrough case in switch.
        console.log("even");
        //这里没有break会穿透到下面的case
      case 1:
        console.log("odd");
        break;
    }
    
    switch (x % 3) {
      case 0://case代码块为空不进行检查
      case 1:
        console.log("Acceptable");
        break;
      case 2:
        console.log("This is *two much*!");
        break;
    }
    
    支持React的Function组件
    const Greeter = ({ name = "world" }) => <div>Hello, {name}!</div>;
    // Properties get validated
    let example = <Greeter name="TypeScript 1.8" />;
    
    module / global 增强

    declare module/global {}都不能向顶级模块增加新项。只能做“patch”

    //observable.ts
    export class Observable<T> {
      age: T;
      constructor(age: T) {
        this.age = age;
      }
    }
    
    //map.ts
    export {};
    declare module "./observable" {
      // 通过使用interface合并来增强Observable
      interface Observable<T> {
        name: string;
      }
      interface NewMap {}
    }
    
    //consumer.ts
    import { Observable, NewMap } from "./observable";
    let o: Observable<number> = {
      name: "1",
      age: 1,
    };
    let map: NewMap = {};
    

    全局作用域增强

    export {};
    declare global {
      interface Array<T> {
        mapToNumbers(): number[];
      }
    }
    Array.prototype.mapToNumbers = () => {
      return [1];
    };
    
    支持字符串字面量作为类型
    type stringLiteral = "ease-in" | "ease-out" | "ease-in-out"
    
    增强联合类型与交叉类型的类型推断
    --outFile

    使用该配置项,会将所有全局文件连接为一个文件,如果使用--module 指定amd system的模块规范,会将这些模块放在全局文件之后

    --allowSyntheticDefaultImports

    但是我实际并没有测试出来

    因为cjs规范中,module.exports.default用于定义默认导出

    允许 ‘import x from y’ 当module没有定义它的默认export

    允许循环用使用let/const
    增强for…in循环代码块的检查
    --allowJs

    打开该项配置,允许.js文件加入tsc编译

    支持对this使用is类型守护

    class FileSystemObject {
      isFile(): this is File {
        return this instanceof File;
      }
      isDirectory(): this is Directory {
        return this instanceof Directory;
      }
      isNetworked(): this is Networked & this {
        return this.networked;
      }
      constructor(public path: string, private networked: boolean) {}
    }
    
    --pretty

    使用它你可以看到更漂亮的命令行报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值