如何在 TypeScript (Node.js) 包中包含全局文件类型声明

Nic*_*tte 13 javascript types node.js typescript webpack

我正在开发一个包,计划在 npmjs 上公开发布。我们称之为“文本包”。

我希望默认情况下安装该软件包时,您可以.txt直接导入文件并获取正确的类型(开箱即用),如下所示:

import text from './file.txt'
Run Code Online (Sandbox Code Playgroud)

text变量将是类型,string因为包已经定义了它的类型,使用类似这样的东西(在 global.d.ts 中):

declare module '*.txt' {
    export const text: string;
    export default text;
}
Run Code Online (Sandbox Code Playgroud)

如果我将 global.d.ts 包含在我的包中,并且从该包中导入某些内容,那么在导入文件时我将自动获得正确的类型.txt

但问题是有时我只需要导入一个.txt文件,而不需要从“文本包”导入任何内容,这就是为什么我想知道是否有某种方法,当您安装一个包来安装一个全局类型时,该全局类型不会需要导入其他任何内容才能应用该类型。

换句话说,一旦您安装了我的“txt 包”,它将立即declare module '*.txt'适用于我的整个项目。

有没有办法做到这一点,或者安装我的包的人必须声明自己的全局类型(例如,declarations.d.ts)才能.txt全局导入文件?

我知道即使导入类型有效,它仍然需要 Webpack 或其他捆绑器才能真正工作,但这个问题只是关于类型。

Nic*_*tte 7

简短的回答是:

如果不导入引用该类型的文件,TypeScript 不支持全局类型。

更多细节:

我发现这样做的一个例子是 Next.js - 使用它创建 TypeScript 应用程序时,npx create-next-app@latest --typescript您可以开始导入*.css文件(例如)并获取正确的类型。

我感到困惑的是,我最初认为该类型来自,next-env.d.ts但即使我删除了该文件,*.css导入仍然可以在 Visual Studio 代码中工作。但原因是pages目录中的一个文件正在导入 Next.js 的index.d.ts文件。

基本上,在 Visual Studio Code 中,一旦您在项目中的某个位置导入类型,如果它是全局的,那么它就可以在任何地方访问。

解决方法

那么当前的 TypeScript 功能可以做什么呢?为了支持新的文件类型,您将需要一个文件加载器,例如 Webpack。合乎逻辑的做法是在文件加载器本身中添加对文件类型声明的引用。这样,一旦您将文件加载器配置为能够导入文件,您将继承该类型:

  1. txt.d.ts在我们的包的源目录中创建一个(例如src) - 您可以使用该文件的任何名称,这并不重要
  2. 如果您使用 eslint,请添加一个条目以忽略类型文件(例如'src/*.d.ts'在您的ignorePatterns选项中
  3. 由于您要在源中添加一个d.ts不受 管理的文件tsc,因此您需要添加一个将执行以下操作的脚本:
    1. 复制txt.d.ts到包的编译文件的目标目录中
    2. 将此行添加到包文件加载器的顶部(例如loader/index.d.ts/// <reference types="../txt" />\r\n- 这会将声明文件链接回包中。请注意,您可以将此引用添加到包的任何文件中。

此解决方法仅在您导入引用回声明的文件后才有效 - 这是 TypeScript 知道此类型存在的唯一方法(请参阅https://github.com/microsoft/TypeScript/issues/49124)。

另一种选择还可以是添加手动步骤(在自述文件中)来添加全局类型声明文件。

  • 您可以使用 NPM 安装后脚本来为您生成该文件吗? (2认同)

Hos*_*our 5

要捆绑全局类型,请执行以下操作。表格打字稿

  • 在typeRoots指定默认类型目录。 "typeRoots": ["./src/types"].例如
  • /src/types/global.d.ts在指定目录下创建文件
  • 在里面的文件中声明你的类型,如果你还没有导出任何东西,declare global {}请确保有。export {}