为啥 TypeScript 将 .default 添加到全局定义的导入中?

Posted

技术标签:

【中文标题】为啥 TypeScript 将 .default 添加到全局定义的导入中?【英文标题】:Why is TypeScript adding .default to a globally defined import?为什么 TypeScript 将 .default 添加到全局定义的导入中? 【发布时间】:2017-04-30 02:31:39 【问题描述】:

我有一个外部库 thing.d.ts 文件,里面有一个全局定义:

declare var thing: ThingStatic;
export default thing;

我在我的 TypeScript 中引用了 npm 模块:

import thing from 'thing';
...
thing.functionOnThing();

当我转译 TS(针对 ES6)时,它看起来像这样:

const thing_1 = require("thing");
...
thing_1.default.functionOnThing();

这会引发错误:

无法读取未定义的属性“functionOnThing”

为什么 TypeScript 在thing_1functionOnThing() 之间添加.default

ThingStatic 上没有名为 default 的属性,.d.ts 文件定义的底层 JS 对象上也没有 default 属性。

TypeScript 为什么要添加该属性,我该如何停止它?

【问题讨论】:

【参考方案1】:
import thing from 'thing';

这行代码意思“从模块'thing'中导入default导出并绑定到本地名称thing”。

TypeScript 会按照您的要求执行并访问模块对象的 default 属性。

你可能想写的是

import * as thing from 'thing';

【讨论】:

好的,现在我的 TypeScript 中有thing.default,所以至少我可以解决它。这是我正在使用的库中的错误吗? .d.ts应该怎么写才能导入全局变量? .d.ts 文件应该是 export = thing 而不是 export default thing 我刚刚尝试过,它给了我一个错误:TS2309 An export assignment cannot be used in a module with other exported elements. 好的,我试过在另一个问题中问这个问题***.com/questions/41150148【参考方案2】:

这似乎是全局 TS 定义和tsconfig.json 中的"module": "commonjs" 的错误。

您可以使用全局 TS 定义并将所有输出拼接到一个文件中,也可以使用模块并直接导入它们。

这里的错误是由于require返回了模块上下文,而default的名称无关紧要——它总是变成default...

declare var thing: ThingStatic;
export thing; // Explicit export for thing
export default thing; // Default export for thing

现在require 将返回此上下文,因此使用commonjs 模块:

import module from 'thing';
var thing = module.default; // From the default export
var alsoThing = module.thing; // From the named export

但是,我发现这不一致,所以切换到 es6 模块:

import thing from './thing'; // Import default
import  thing  from './thing'; // Import named
const thing = (await import('path/to/thing.js')).default; // Import dynamic 

【讨论】:

以上是关于为啥 TypeScript 将 .default 添加到全局定义的导入中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在 TypeScript 中导出类实例?

为啥 Typescript 允许将“任何”对象类型分配给类对象?

为啥 Typescript 编译器不会将 .ts 更改为 .js?

为啥人们将 typescript 的类型作为依赖项存储在 package.json(而不是 devDep)中? [复制]

为啥 Typescript 允许将 `a: 1, b: 2` 分配给类型 `a: any | b:任何`? [复制]

为啥 eslint 考虑 JSX 或一些反应 @types undefined,因为将 typescript-eslint/parser 升级到版本 4.0.0