使用 import/require 与主要导入一起导入类型

Importing types alongside main import with import/require

我正在为 airtable 写一个定义文件,不幸的是,他们只导出一个 class 像这样:

...

module.exports = Airtable;

因此,我的 airtable.d.ts 文件如下所示:

declare module "airtable" {
    export type MyType = { ... };

    export class Airtable {
        ...
    }

    export = Airtable;
}

当我导入 Airtable class 时效果很好:

import Airtable = require("airtable");
...
new Airtable(...)

但我也找不到导入 MyType 的方法:

let a: Airtable.MyType;

导致此错误:

'Airtable' only refers to a type, but is being used as a namespace here

并且:

import { MyType } from "airtable";

导致这些错误:

Module "airtable" has no exported member 'MyType'
Module "airtable" resolves to a non-module entity and cannot be imported using this construct

知道如何在继续使用 export =import/require 的同时导入其他导出类型吗?
谢谢。

所以答案实际上取决于您将如何使用这些类型。如果您在自己的项目中使用它们,则需要一个文件(称为 <whatever>.d.ts)来声明一个名为 "airtable" 的模块。在那,你需要导出一些东西。由于您正在导出 class,因此您必须使用 export = X 语法而不是 export X,因为您正在更改整个导出对象而不是添加 属性。在导出对象上(稍后会详细介绍)。至于类型,在 .d.ts 文件中的模块之外,您还可以 decalre 一个全局可用的类型。如果这让您感到不适(或者您担心冲突),您也可以将您的类型放入模块中。由于它是纯 typescript 的东西,所以它不必由任何 js 代码支持。然后你可以像往常一样import/export它:

// my.d.ts

declare module 'airtable' {
  class Airtable {
    constructor(opts?: MyType)
  }
  export = Airtable
}

declare type MyType = string | number

declare module 'AirtableTypes' {
  export type MyString = string
  export type MyNumber = number
}

和用法

// index.ts
import Airtable from 'airtable'
import AirtableTypes from 'AirtableTypes'

const a = new Airtable('a')

const n: MyType = 3

const s: AirtableTypes.MyString = '3'

如果您想向 DefinitelyTyped 添加类型(我相信他们会很感激!),您可以按照指南 here 编写声明文件。

它将指向您

您(正确地)注意到 Airtable 导出单个 class,它与 TS 的配合不是很好。有一些讨论 here. Either way, the above guide will point you at module-class.d.ts,它允许您声明导出的 class 和伴随类型。您不能在上面使用它,因为该格式仅在定义文件位于模块根目录或 @types/<module>.

中时可用
/*~ This declaration specifies that the class constructor function
 *~ is the exported object from the file
 */
export = Airtable

/*~ Write your module's methods and properties in this class */
declare class Airtable {
  constructor(opts?: Airtable.AirtableMethodOptions)
}

/*~ If you want to expose types from your module as well, you can
 *~ place them in this block.
 */
declare namespace Airtable {
  export interface AirtableMethodOptions {
    endpointUrl: string
  }
}