Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 理解tsconfig文件中的esModuleInterop_Typescript - Fatal编程技术网

Typescript 理解tsconfig文件中的esModuleInterop

Typescript 理解tsconfig文件中的esModuleInterop,typescript,Typescript,我正在检查某人的.tsconfig文件,在那里我发现了--esModuleInterop 这是他的.tsconfig文件 { "compilerOptions": { "moduleResolution": "node", "target": "es6", "module": "commonjs", "lib&q

我正在检查某人的
.tsconfig
文件,在那里我发现了
--esModuleInterop

这是他的
.tsconfig
文件

{
  "compilerOptions": {
    "moduleResolution": "node",
    "target": "es6",
    "module": "commonjs",
    "lib": ["esnext"],
    "strict": true,
    "sourceMap": true,
    "declaration": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "declarationDir": "./dist",
    "outDir": "./dist",
    "typeRoots": ["node_modules/@types"]
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modues"]
}
在这里,我的主要问题是什么是
“esModuleInterop”:true、
“allowSyntheticDefaultImports”:true,
。我知道它们有点依赖于
“模块”:“commonjs”,
。有人能用最好的人类语言来解释它吗

allowSyntheticDefaultImports
的官方文档说明

允许从没有默认导出的模块进行默认导入。确实如此 不影响代码发出,只需进行类型检查

这是什么意思?如果没有任何导出默认值,那么我认为导入默认值的唯一用例是初始化一些东西?像单身汉

下面的问题/答案也没有意义

和编译器页面上的
--esModuleInterop
定义

为运行时babel发出_importStar和_importDefault帮助程序 生态系统兼容性和启用--allowSyntheticDefaultImports for 类型系统兼容性


对我来说,似乎也很难理解/理解

esModuleInterop
生成文档中概述的帮助程序。查看生成的代码,我们可以确切地看到这些代码的作用:

//ts 
import React from 'react'
//js 
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importDefault(require("react"));
\uuu importDefault
:如果模块不是
es
模块,则require返回的内容将成为默认值。这意味着如果在
commonjs
模块上使用默认导入,则整个模块实际上是默认的

\uuu importStar
最好在以下章节中描述:

TypeScript将名称空间导入(即
import*视为来自“foo”
)的foo)等同于
const foo=require(“foo”)
。这里的事情很简单,但无法确定要导入的主要对象是原语还是具有调用/构造签名的值。 ECMAScript基本上说名称空间记录是一个普通对象

Babel首先需要输入模块,并检查名为
\uu esModule
的属性。如果
\uu esModule
设置为
true
,则行为与TypeScript相同,但除此之外,它会合成一个名称空间记录,其中:

  • 所有属性都从required模块中提取出来,并作为命名导入提供
  • 最初需要的模块作为默认导入提供
  • 所以我们得到这个:

    // ts
    import * as React from 'react'
    
    // emitted js
    var __importStar = (this && this.__importStar) || function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
        result["default"] = mod;
        return result;
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    var React = __importStar(require("react"));
    
    allowSyntheticDefaultImports
    是所有这些的配套工具,将其设置为false将不会更改发出的帮助程序(它们看起来仍然相同)。但是,如果对commonjs模块使用默认导入,则会引发typescript错误。因此,此
    从'React'
    导入React将引发错误
    模块“…/node\u modules/@types/React/index”'没有默认导出。
    如果
    allowSyntheticDefaultImports
    false

    问题陈述 当我们想将CommonJS模块导入ES6模块代码库时,就会出现问题

    在这些标志之前,我们必须导入带有星号(
    *作为某种东西)的CommonJS模块导入:

    我们可以看到,
    *
    在某种程度上等同于
    导出
    变量。它工作正常,但不符合es6模块规范。在规范中,星形导入中的名称空间记录(
    moment
    ,在本例中)只能是普通对象,不能调用(
    moment()

    解决方案 使用flag
    esModuleInterop
    我们可以按照
    es6
    modules规范导入CommonJS模块。现在我们的导入代码如下所示:

    // index.ts file in our app
    import moment from 'moment'
    moment(); // compliant with es6 module spec
    
    // transpiled js with esModuleInterop (simplified):
    const moment = __importDefault(require('moment'));
    moment.default();
    
    它可以工作,并且在es6模块规范中完全有效,因为
    moment
    不是来自star导入的名称空间,而是默认导入

    但是它是如何工作的呢?正如您所看到的,因为我们进行了默认导入,所以我们在
    对象上调用了
    default
    属性。但是我们没有在矩库中的
    exports
    对象上声明
    default
    属性。关键是
    \uuu importDefault
    功能。它将模块(
    导出
    )分配给CommonJS模块的
    默认
    属性:

    var __importDefault = (this && this.__importDefault) || function (mod) {
        return (mod && mod.__esModule) ? mod : { "default": mod };
    };
    
    如您所见,我们按原样导入es6模块,但CommonJS模块使用
    default
    键包装到一个对象中。这使得在CommonJS模块上导入默认值成为可能

    \uuu importStar
    执行类似的工作-它返回未触及的esModules,但将CommonJS模块转换为具有
    默认属性的模块:

    // index.ts file in our app
    import * as moment from 'moment'
    
    // transpiled js with esModuleInterop (simplified):
    const moment = __importStar(require("moment"));
    // note that "moment" is now uncallable - ts will report error!
    
    合成进口 那么
    allowSyntheticDefaultImports
    是做什么用的呢?现在,文档应该清楚了:

    允许从没有默认导出的模块进行默认导入。这不会影响代码的发出,只需进行类型检查。


    moment
    打字中,我们没有指定默认导出,也不应该指定,因为它仅在启用标志
    esModuleInterop
    时可用。因此,如果要从没有默认导出的第三方模块导入默认值,则
    allowSyntheticDefaultImports
    不会报告错误。

    在引入
    --esModuleInterop
    标志之前,
    import*作为“时刻”的时刻
    不正确
    import-moment=require('moment')
    was.@AluanHaddad这两种方法似乎都有效:import-foo=require('foo')或import*as-foo from'foo'@tomwang1013将
    import*as-m
    形式的导入不允许
    m()
    新建m
    。一些模块加载器和绑定器我将对此进行回避,但这违反了ECMAScriptspec@AluanHaddad我明白你的意思了。我的意思是typescript将转换它们并处理它们equal@tomwang1013不,那不对。模块的功能不仅取决于编译器(在本例中为TypeScript),还取决于模块
    var __importDefault = (this && this.__importDefault) || function (mod) {
        return (mod && mod.__esModule) ? mod : { "default": mod };
    };
    
    // index.ts file in our app
    import * as moment from 'moment'
    
    // transpiled js with esModuleInterop (simplified):
    const moment = __importStar(require("moment"));
    // note that "moment" is now uncallable - ts will report error!
    
    var __importStar = (this && this.__importStar) || function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
        result["default"] = mod;
        return result;
    };