编写 .d.ts 文件以便我可以与 JavaScript 和 TypeScript 共享常量?

Dan*_*com 3 javascript types node.js typescript visual-studio-code

我正在开发一个 node.js 项目,由于历史原因,该项目同时涉及 TypeScript 和 JavaScript。我想设置一些可以在两种语言中使用的项目范围的常量。显而易见:编写一个.js包含常量的.d.ts文件,以及一个包含 TypeScript 使用类型的文件。但是没有:几个小时的解决问题(和 RTFMing)让我一无所获。

这是我对常量文件的第一次尝试:

// constants.js
const MY_CONST_1 = 1;
exports.MY_CONST_1 = MY_CONST_1;
Run Code Online (Sandbox Code Playgroud)

...以及使用它的 JavaScript:

// consumer.js
let constants = require('./constants');
let one = constants.MY_CONST_1;
Run Code Online (Sandbox Code Playgroud)

这很有效,但是当我在 TypeScript 中尝试显而易见的事情时:

// consumer.ts
import * as constants from './constants';
let one: number = constants.MY_CONST_1;
Run Code Online (Sandbox Code Playgroud)

不:error TS2307: Cannot find module './constants'.所以,必须constants.d.ts在与文件相同的目录中写入一个constants.js文件,对吗?听起来很简单,但六次不同的尝试都产生了完全一致的结果。无论我做什么,Typescript 都会抱怨error TS2306: File '/Users/griscom/Documents/Work/test/constants.d.ts' is not a module

那么,一个成功的constants.d.ts文件会是什么样子呢?或者,如果我必须进行更改constants.js才能使其正常工作,它们会是什么?

PS这是我的tsconfig.json文件:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "noImplicitReturns": true
  }
}
Run Code Online (Sandbox Code Playgroud)

(这似乎是一个如此简单而明显的需求;令人沮丧的是这个过程是多么不透明。)

Aar*_*all 5

选项1: allowJs

尝试使用编译器选项allowJs: true。这将允许您的原始导入./constants工作,即使它是一个.js文件,而无需创建单独的.d.ts文件。TypeScript 将理解.js文件中的可推断类型,例如,您将获得MY_CONST_1作为数字的类型检查。

正如您在评论中所说,这需要将源文件与输出文件分开,因为它无法在与 JS 源文件相同的位置输出 JS 文件。

选项 2:constants.d.ts声明文件

鉴于您的源文件如下所示:

// constants.js
export const MY_CONST_1 = 1;
Run Code Online (Sandbox Code Playgroud)

您可以编写一个如下所示的constants.d.ts文件:

// constants.d.ts
export const MY_CONST_1: number;
Run Code Online (Sandbox Code Playgroud)

您之前尝试使用的地方是使用 declaration module,它用于声明外部模块的类型(如 from node_modules)。在这种情况下,只需将constants.d.ts文件放在constants.js与 using相同的目录中,export就会告诉 TS 它是一个导出该值的 JS 模块:

import { MY_CONST_1 } from "./constants";
import * as constants from "./constants";
Run Code Online (Sandbox Code Playgroud)

需要记住的重要一点是,.d.ts不会根据.js文件检查文件以确保它实际上是正确的,这取决于您。因此,如果您对.js文件进行更改,则必须确保.d.ts相应地正确更新文件。编译错误或缺少编译错误并不意味着它正确与否。这是allowJs存在的原因之一,因为它避免了这种泄漏。