美文网首页
TSConfig文件详解18

TSConfig文件详解18

作者: 从零开始学ArchLinux | 来源:发表于2024-07-03 23:47 被阅读0次

    编译器配置项-compilerOptions

    输出相关配置项02

    降级迭代-downlevelIteration

    降级是 TypeScript 的术语,表示转换为旧版 JavaScript。downlevelIteration选项是为了支持现代JavaScript的迭代概念能够更准确地在旧版 JavaScript 中运行。

    ECMAScript 6 添加了几个新的迭代语法:for / of 循环(for (el of arr))、数组展开([a, ...b])、参数展开(fn(...args))和 Symbol.iterator。如果存在 Symbol.iterator已经被实现,则 downlevelIteration 允许在 ES5 环境中更准确地使用这些迭代原语。

    示例1:在for/of语法中的作用

    有以下TypeScript 代码:

    const str = "Hello!";
    for (const s of str) {
      console.log(s);
    }
    

    未启用downlevelIteration时,一个在Object上的for/of循环将降级为传统的for循环:

    "use strict";
    var str = "Hello!";
    for (var _i = 0, str_1 = str; _i < str_1.length; _i++) {
        var s = str_1[_i];
        console.log(s);
    }
    

    这通常是人们所期望的,但它并不 100% 符合 ECMAScript 迭代协议。某些字符串,例如表情符号 (😜),其 .length 为 2(甚至更大!),但在 for-of 循环中应作为 1 个单位进行迭代。有关更详细的解释,请参阅 Jonathan New 的这篇博文

    启用downlevelIteration后,TypeScript 将使用辅助函数检查Symbol.iterator实现(原生或 polyfill)。如果缺少此实现,您将回退到基于索引的迭代。

    "use strict";
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    var e_1, _a;
    var str = "Hello!";
    try {
        for (var str_1 = __values(str), str_1_1 = str_1.next(); !str_1_1.done; str_1_1 = str_1.next()) {
            var s = str_1_1.value;
            console.log(s);
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (str_1_1 && !str_1_1.done && (_a = str_1.return)) _a.call(str_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    

    可以通过tslib中的importHelpers减少内联 JavaScript 的数量:

    "use strict";
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    var e_1, _a;
    var str = "Hello!";
    try {
        for (var str_1 = __values(str), str_1_1 = str_1.next(); !str_1_1.done; str_1_1 = str_1.next()) {
            var s = str_1_1.value;
            console.log(s);
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (str_1_1 && !str_1_1.done && (_a = str_1.return)) _a.call(str_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    

    注意: 如果运行时不存在Symbol.iterator,那么启用downlevelIteration并不能提高合规性。

    示例2:展开数组上的作用

    下边是展开数组的一个示例:

    // Make a new array whose elements are 1 followed by the elements of arr2
    const arr = [1, ...arr2];
    

    根据描述,降级到 ES5 听起来很容易:

    // The same, right?
    const arr = [1].concat(arr2);
    

    但是,在某些罕见情况下,情况会有所不同。

    例如,如果源数组缺少一个或多个的空元素,则扩展语法会将每个空元素替换为undefined,而.concat则会保留它们。

    // Make an array where the element at index 1 is missing
    let arrayWithHole = ["a", , "c"];
    let spread = [...arrayWithHole];
    let concatenated = [].concat(arrayWithHole);
    console.log(arrayWithHole);
    // [ 'a', <1 empty item>, 'c' ]
    console.log(spread);
    // [ 'a', undefined, 'c' ]
    console.log(concatenated);
    // [ 'a', <1 empty item>, 'c' ]
    

    for / of语法一样,启用downlevelIteration将使用Symbol.iterator (如果存在) 来更准确地模拟 ES 6 行为

    相关文章

      网友评论

          本文标题:TSConfig文件详解18

          本文链接:https://www.haomeiwen.com/subject/ytjicjtx.html