【问题标题】:Use import instead require with typeof使用 import 而不是 require 和 typeof
【发布时间】:2021-02-09 19:42:11
【问题描述】:

我有一个第三方 ES6 类的 require 语句,如下所示:

const Machine: typeof IMachine = require('lib')

IMachine 是我对导入类的类型定义:

export declare class IMachine {
  public constructor(opts: MachineOptions)
  public static list(callback: (err?: Error, machines?: IMachine[]) => void): void
}

declare interface MachineOptions {
  name: string
}

如何使用import 语句来表达这一点?

更新

基于Aluans answer我创建了一个repro:https://github.com/AlexZeitler/sourced-typings-repro

我得到的编译器错误:


src/Market.ts:11:10 - error TS2339: Property 'rehydrate' does not exist on type 'Market'.

11     this.rehydrate(snapshot, events)
            ~~~~~~~~~

src/Market.ts:11:20 - error TS2552: Cannot find name 'snapshot'. Did you mean 'snapshots'?

11     this.rehydrate(snapshot, events)
                      ~~~~~~~~

  src/Market.ts:6:15
    6   constructor(snapshots?, events?) {
                    ~~~~~~~~~~
    'snapshots' is declared here.

src/Market.ts:15:10 - error TS2339: Property 'id' does not exist on type 'Market'.

15     this.id = param.id
            ~~

src/Market.ts:16:10 - error TS2339: Property 'digest' does not exist on type 'Market'.

16     this.digest('init', param)
            ~~~~~~

src/Market.ts:17:10 - error TS2339: Property 'emit' does not exist on type 'Market'.

17     this.emit('initialized', param, this)

import 语句显示此警告:

Could not find a declaration file for module 'sourced'. '/Users/alex/src/sourced-typings-repro/node_modules/sourced/dist/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/sourced` if it exists or add a new declaration (.d.ts) file containing `declare module 'sourced';`ts(7016)

原始问题中的示例基于我的另一个问题,该问题导致关于 typeof + require 与导入样式的问题:

Create typings for 3rd party library using class

【问题讨论】:

  • import { Imachine } from 'lib'?
  • 你不能:ES import 没有类型的概念,TS 没有扩展它的语法。

标签: typescript


【解决方案1】:

根据您提供的 repo,请执行以下操作:

tsconfig.json 中:

  • 删除"compilerOptions.typesRoot"
  • "include" 更新为["src/**/*.ts", "types/**/*.ts"](可选择将types 文件夹移动到src 并保持"include" 不变)

types/sourced.d.ts的内容设置为:

declare module 'sourced' {
  import { EventEmitter } from 'events'
  class SourcedEntity extends EventEmitter {
    constructor(snapshots?, events?)
    public rehydrate(snapshot?, events?): void
    public id: string
    public digest(method: string, param: any): void
    public enqueue(method: string, param: any): void
  }
  // export default SourcedEntity <-- PREVIOUSLY INCORRECT
  export { SourcedEntity }
}

更多上下文/更新

当您将鼠标悬停在原始存储库中的 from "sourced" 上时,您会看到一个错误:

Could not find a declaration file for module 'sourced'. '/Users/ymagio/pr/so/sourced-typings-repro/node_modules/sourced/dist/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/sourced` if it exists or add a new declaration (.d.ts) file containing `declare module 'sourced';`ts(7016)

我不知道为什么compilerOptions.typesRoot 没有被正确拾取,如果types/sourced.d.ts 首先是正确的。无论如何:declare module 'sourced' 是 TS 编译器建议的为无类型模块提供类型的方法,我在多个场合都成功使用了它。

我查看了node_modules/sourced,结果发现我最初的答案有点——没有default export,并且模块使用了CommonJS exports 的形状:

{
  SourcedEntity: [Getter],
  Entity: [Getter],
  Value: [Getter],
  SourcedValue: [Function: _default]
}

Typescript 处理与different types of modules(ES2015、CommonJS、AMD、UMD)相关的许多复杂性和极端情况,所以说实话,这个话题可能会让人很困惑。我的指导方针是尽可能地坚持 ES2015 标准。如果我不确定从模块中导出的确切内容,我会尝试:import Default, * as All from 'untyped-module'console.log(Default, All)

【讨论】:

  • 谢谢,我所做的是基于 Aluan (stackoverflow.com/a/66056940/90800) 的回答。我注意到的一个权衡是,在我的测试中,类型信息不存在(我可以“包含”我的测试文件夹,这样它就可以工作了)。我想了解两个答案的差异(好处/权衡)。
【解决方案2】:

放弃这种方法。

相反

额外类型/lib.d.ts

export = IMachine;

declare class IMachine {
  constructor(opts: MachineOptions);
  static list(callback: (err?: Error, machines?: IMachine[]) => void): void
};

interface MachineOptions {
  name: string;

}

tsconfig.json

 {
   "compilerOptions": {
       "typeRoots": [
         "./extra-types",
         "node_modules/@types"
      ],
      "esModuleInterop": true,
      "moduleResolution": "node"
  }

终于

import Machine from "lib";

【讨论】:

  • 谢谢,我必须将lib.d.ts 的内容包装在declare module 'lib' { ... } 中,并从declare class IMachine 中删除declare 关键字才能使其正常工作。
  • 这意味着您的设置有所不同
  • 我根据我打算使用的 lib 创建了一个 repro:github.com/AlexZeitler/sourced-typings-repro。原始问题中的示例基于我的另一个问题,该问题导致有关typeof + requireimport 风格的问题:stackoverflow.com/questions/57868450/…
  • 我已在问题中添加了有关错误/警告的更多详细信息。
猜你喜欢
  • 2019-08-31
  • 2020-04-12
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2021-10-28
  • 1970-01-01
  • 2021-05-28
  • 2021-12-27
相关资源
最近更新 更多