美文网首页
TSConfig文件详解28

TSConfig文件详解28

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

编译器配置项-compilerOptions

互操作约束相关配置项01

允许合成默认导入- allowSyntheticDefaultImports

allowSyntheticDefaultImports 设置为 true 时,可以使用下边的 import

import React from "react";

替代:

import * as React from "react";

如果一个模块没有指定默认导出,在下边的示例中,如果 allowSyntheticDefaultImport 没有设置为 true

// @filename: utilFunctions.js
const getStringLength = (str) => str.length;
 
module.exports = {
  getStringLength,
};
 
// @filename: index.ts
import utils from "./utilFunctions";
Module '"/home/runner/work/TypeScript-Website/TypeScript-Website/packages/typescriptlang-org/utilFunctions"' has no default export.
 
const count = utils.getStringLength("Check JS");

上边的代码抛出一个错误,因为导入的 utilFunctions 文件没有指定默认的导出对象。尽管感觉上应该可以这样写。为了方便起见,如果没有指定默认导出,像 Babel 这样的转译器会自动创建一个默认导出对象默认值,模块转译后有点像以下代码:

// @filename: utilFunctions.js
const getStringLength = (str) => str.length;
const allFunctions = {
  getStringLength,
};
module.exports = allFunctions;
module.exports.default = allFunctions;

这个配置选项不会影响TypeScript输出的JavaScript代码,只是为了类型检查。这个选项使 TypeScript 的行为与 Babel 保持一致,输出的额外代码用来指定默认导出,这样更符合人类的使用习惯。

ES模块互操作 - esModuleInterop

默认情况下(esModuleInteropfalse或者未设置)TypeScript 将 CommonJS / AMD / UMD 模块视为与 ES6 模块类似。在这样做的过程中,以下假设的两个场景是有缺陷的:

  • import * as moment from "moment" 这样的命名空间导入的作用与 const moment = require("moment") 相同

  • import moment from "moment" 默认导入的作用与 const moment = require("moment").default 相同

对应的会导致以下两个问题:

  • ES6 模块规范规定,命名空间导入(import * as x)只能是一个对象,由于TypeScript 将其视为与= require("x")相同,所以 TypeScript 将允许将导入视为函数,并被允许调用。但是根据ES规范,这是无效的。

  • 虽然准确符合 ES6 模块规范,但大多数 CommonJS / AMD / UMD 的模块并不像 TypeScript 的实现那么严格

启用 esModuleInterop 这两个问题将在TypeScript 转译代码的过程中被解决。第一个改变了编译器中的行为,第二个由两个新的辅助函数修复,它们提供了辅助功能以确保输出的 JavaScript 的兼容性:

import * as fs from "fs";
import _ from "lodash";
fs.readFileSync("file.txt", "utf8");
_.chunk(["a", "b", "c", "d"], 2);

禁用 esModuleInterop 时:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const lodash_1 = require("lodash");
fs.readFileSync("file.txt", "utf8");
lodash_1.default.chunk(["a", "b", "c", "d"], 2);

esModuleInterop 设置为 true 时:

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const lodash_1 = __importDefault(require("lodash"));
fs.readFileSync("file.txt", "utf8");
lodash_1.default.chunk(["a", "b", "c", "d"], 2);

注意:命名空间 import import * as fs from "fs" 仅考虑导入对象所拥有的属性(基本上是在对象上设置的属性,而不是通过原型链设置的属性)。如果导入的模块使用继承属性定义其 API,则需要使用默认导入形式(import fs from "fs"),或者禁用 esModuleInterop

注意:您可以通过启用 importHelpers 使TypeScript输出更简洁的JavaScript代码:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs"));
const lodash_1 = tslib_1.__importDefault(require("lodash"));
fs.readFileSync("file.txt", "utf8");
lodash_1.default.chunk(["a", "b", "c", "d"], 2);

启用 esModuleInterop 还将启用 allowedSyntheticDefaultImports

相关文章

网友评论

      本文标题:TSConfig文件详解28

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