TypeScript 2.1介绍


当前第2页 返回上一页

首先,安装tslib实用程序库:

npm install tslib

其次,使用--importHelpers命令编译文件:

tsc --module commonjs --importHelpers a.ts

因此,给定以下输入,生成的.js文件将包含导入到tslib并使用其中的__assign帮助程序而不是内联它。

export const o = { a: 1, name: "o" };
export const copy = { ...o };
"use strict";
var tslib_1 = require("tslib");
exports.o = { a: 1, name: "o" };
exports.copy = tslib_1.__assign({}, exports.o);

无类型的导入

传统上,TypeScript对于如何导入模块过于严格。这是为了避免拼写错误并阻止用户错误地使用模块。

但是,在很多时候,您可能只想导入可能没有自含.d.ts文件的现有模块。以前这是一个错误。从TypeScript 2.1开始,这现在变得更加容易。

使用TypeScript 2.1,您可以导入JavaScript模块而无需类型声明。如果存在类型声明(例如,declare module "foo" { ... },或node_modules/@types/foo)仍然具有优先权。

对没有声明文件的模块的导入仍将被标记为--noImplicitAny下的错误。

示例

// Succeeds if `node_modules/asdf/index.js` exists
import { x } from "asdf";

支持--target ES2016,--target ES2017和--target ESNext

TypeScript 2.1支持三个新的目标值--target ES2016,--target ES2017和--target ESNext。

使用target --target ES2016将指示编译器不要转换特定于ES2016的功能,例如**运算符。

同样,--target ES2017将指示编译器不要转换特定于ES2017的特性,如async/ await。

--target ESNext针对最新支持的ES提议功能。

改进的any推理

以前,如果TypeScript无法确定变量的类型,则会选择any类型。

let x;      // implicitly 'any'
let y = []; // implicitly 'any[]'

let z: any; // explicitly 'any'.

使用TypeScript 2.1,而不仅仅是选择any,TypeScript将根据您最后分配的内容推断类型。

仅在设置--noImplicitAny时才启用此选项。

示例

let x;

// You can still assign anything you want to 'x'.
x = () => 42;

// After that last assignment, TypeScript 2.1 knows that 'x' has type '() => number'.
let y = x();

// Thanks to that, it will now tell you that you can't add a number to a function!
console.log(x + y);
//          ~~~~~
// Error! Operator '+' cannot be applied to types '() => number' and 'number'.

// TypeScript still allows you to assign anything you want to 'x'.
x = "Hello world!";

// But now it also knows that 'x' is a 'string'!
x.toLowerCase();

现在也对空数组进行了相同类型的跟踪。

声明为没有类型注释且初始值为[]的变量被视为隐式any[]变量。然而,每个后续的x.push(value),x.unshift(value)或者x[n] = value操作根据添加到的元素来演变变量的类型。

function f1() {
    let x = [];
    x.push(5);
    x[1] = "hello";
    x.unshift(true);
    return x;  // (string | number | boolean)[]
}

function f2() {
    let x = null;
    if (cond()) {
        x = [];
        while (cond()) {
            x.push("hello");
        }
    }
    return x;  // string[] | null
}

隐含任何错误

这样做的一个很大好处是,在运行--noImplicitAny时你会看到更少的隐式any错误。仅当编译器无法知道没有类型注释的变量类型时,才会报告隐式any错误。

示例

function f3() {
    let x = [];  // Error: Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined.
    x.push(5);
    function g() {
        x;    // Error: Variable 'x' implicitly has an 'any[]' type.
    }
}

更好地推断文字类型

字符串,数字和布尔文字类型(例如"abc",1和true)仅在存在显式类型注释时才推断。从TypeScript 2.1开始,始终为const变量和readonly属性推断文字类型。

为没有类型注释的const变量或readonly属性推断的类型是文字初始值设定项的类型。为具有初始值设定项且没有类型注释的let变量,var变量,参数或非readonly属性推断的类型是初始化程序的扩展文字类型。对于字符串文字类型的加宽类型是string,number对于数字文字类型,boolean对于true或false,以及包含枚举文字类型的枚举。

示例

const c1 = 1;  // Type 1
const c2 = c1;  // Type 1
const c3 = "abc";  // Type "abc"
const c4 = true;  // Type true
const c5 = cond ? 1 : "abc";  // Type 1 | "abc"

let v1 = 1;  // Type number
let v2 = c2;  // Type number
let v3 = c3;  // Type string
let v4 = c4;  // Type boolean
let v5 = c5;  // Type number | string

可以通过显式类型注释来控制文字类型扩展。具体来说,当为没有类型注释的const位置推断出文字类型的表达式时,该const变量将推断出一个加宽的文字类型。但是,当const位置具有显式文字类型注释时,该const变量将获得非加宽文字类型。

示例

const c1 = "hello";  // Widening type "hello"
let v1 = c1;  // Type string

const c2: "hello" = "hello";  // Type "hello"
let v2 = c2;  // Type "hello"

使用超级调用的返回值为'this'

在ES2015中,返回对象的构造函数隐式地将this值替换为super()的任何调用者。因此,有必要捕获super()的任何潜在返回值,并且使用this替换它。此更改允许使用Custom Elements,该元素利用此特性用用户编写的构造函数初始化浏览器分配的元素。

示例

class Base {
    x: number;
    constructor() {
        // return a new object other than `this`
        return {
            x: 1,
        };
    }
}

class Derived extends Base {
    constructor() {
        super();
        this.x = 2;
    }
}

输出:

var Derived = (function (_super) {
    __extends(Derived, _super);
    function Derived() {
        var _this = _super.call(this) || this;
        _this.x = 2;
        return _this;
    }
    return Derived;
}(Base));
这种变化导致扩展内置类(如,Error,Array,Map,等)的行为中断。

配置继承

通常,一个项目有多个输出目标,例如ES5和ES2015,调试和生产,CommonJS和System;这两个目标之间只有少数配置选项发生变化,维护多个tsconfig.json文件可能很麻烦。

TypeScript 2.1支持使用extends继承配置,其中:

  • extends是tsconfig.json中一个新的顶级属性(包括compilerOptions,files,include,和exclude)。
  • extends的值必须是包含要继承的另一个配置文件的路径的字符串。
  • 首先加载基本文件中的配置,然后由继承配置文件中的配置覆盖。
  • 不允许配置文件之间的循环。
  • files,include和exclude从继承配置文件覆盖基本配置文件中的那些。
  • 配置文件中找到的所有相对路径将相对于它们所源自的配置文件进行解析。

示例

configs/base.json:

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

tsconfig.json:

{
  "extends": "./configs/base",
  "files": [
    "main.ts",
    "supplemental.ts"
  ]
}

tsconfig.nostrictnull.json:

{
  "extends": "./tsconfig",
  "compilerOptions": {
    "strictNullChecks": false
  }
}

新 --alwaysStrict

使用--alwaysStrict调用编译器的原因:

  1. 以严格模式解析所有代码。
  2. 在每个生成的文件上面写入指令"use strict";。

模块在严格模式下自动解析。对于非模块代码,建议使用新标志。


标签:TypeScript

返回前面的内容

相关阅读 >>

javascript的超集是什么

typescript 声明文件原理

typescript jsx

typescript 模块

如何从javascript到typescript

angular实现只执行正在开发的新单元测试

typescript 模块解析

typescript和javascript有什么区别

分享angular中关于表单的一些知识点

浅析typescript和react中使用ref的方法

更多相关阅读请进入《typescript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...