【问题标题】:Detecting `import * as name` token检测`import * as name`标记
【发布时间】:2017-03-22 12:51:53
【问题描述】:

我正在编写一些代码,我只想将其应用于import * as name from 'module-name' 语法中的令牌。

有没有办法做到这一点?我记得有一个 __ESModule 标志或类似的东西,但不在官方规范中,所以我不确定这是否是正确的方法(我找不到确切的文章谈论它,参考会有很大的帮助)。

即这就是我想要的(在示例中使用 TypeScript):

import * as someModule from 'module-name'
import someDefault from 'module-name'
import { someNamed } from 'module-name'
import otherImport = require('cjs-module')

let somethingElse = {} // anything
checkIsStarModule(someModule) // true
checkIsStarModule(someDefault) // false
checkIsStarModule(someNamed) // false
checkIsStarModule(otherImport) // false
checkIsStarModule(somethingElse) // false

描述import * as name ... 语法的正确名称是什么? :)

编辑:为问题添加一些上下文。

我正在做类似于aureliaFrameworkConfiguration 的事情。

如上所述,我只想将其应用于someModule。这是因为我不想在不是模块的东西上意外执行configure() 方法。

我的 API 是 get(key: Newable<T> | T): Promise<T>,我允许消费者像 key 一样输入任何东西(Newable<T> 就是任何类)。

感谢@estus on __esModule,我意识到它仅用于互操作,因此在这种情况下没有用。

【问题讨论】:

  • 这个检查的目的是什么? __esModule 是检测 ES6 导入的方式。
  • 如果一个模块做import * as Foo from './Foo'; export {Foo};,你想要什么?然后,如果您import {Foo} from './index';Foo 对象将是星号导入,但不是来自当前文件。了解更多关于您实际尝试解决的用例可能会有所帮助。
  • @loganfsmyth,那很好。这实际上是我所期望和寻找的。​​span>
  • 考虑到问题的上下文,我看不出应该强制使用 ES6 模块的原因。问题是没有原生的 ES6 模块(在某些方面是特殊的)。转译模块是普通对象。如果您想为configure 断言一个参数,可以通过类型检查、实例检查或鸭子类型来完成(* 导入不是前两者的最佳选择)。
  • 我将支持@estus 的观点,我个人认为不得不使用这样的 API 会非常恼火。

标签: javascript typescript ecmascript-6 es6-modules


【解决方案1】:

没有什么能真正将module namespace objects 与其他人区分开来,任何人都可以创建这样的对象。你可以测试一下

function isModuleNamespaceLike(o) {
    return o === Object(o)
    && o[Symbol.toStringTag] === "Module"
    && Object.getPrototypeOf(o) === null
    && !Object.isExtensible(o)
    && Object.getOwnPropertyNames(o).every(function(p) {
        var d = Object.getOwnPropertyDescriptor(o, p);
        return d.enumerable && !d.configurable;
    });
}

或尝试查找__esModule,但这取决于您的转译器。

【讨论】:

  • 如果你不介意 toStringTag 被其他对象覆盖,也可以在 ES6 中使用 Object.prototype.toString.call(obj) === "[object Module]"
  • @loganfsmyth 哦,对了,我怎么会错过that!我想知道o[Symbol.iterator] 在所有模块命名空间对象上是否具有相同的标识……
  • 谢谢。也喜欢@loganfsmyth 的回答。我会保持简单,看看结果如何。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-25
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2023-03-07
  • 2022-12-28
  • 2021-10-15
相关资源
最近更新 更多