编写.d.ts文件以便与JavaScript和TypeScript共享常量?
我正在做一个node.js项目,由于历史原因,它同时涉及TypeScript和JavaScript。我想设置一些可以在两种语言中使用的项目范围常量。显而易见:编写一个包含常量的编写.d.ts文件以便与JavaScript和TypeScript共享常量?,javascript,node.js,typescript,types,visual-studio-code,Javascript,Node.js,Typescript,Types,Visual Studio Code,我正在做一个node.js项目,由于历史原因,它同时涉及TypeScript和JavaScript。我想设置一些可以在两种语言中使用的项目范围常量。显而易见:编写一个包含常量的.js文件,以及一个包含TypeScript使用类型的.d.ts文件。但是没有:我花了几个小时来解决这个问题(还有RTFMing),结果一事无成 这是我第一次尝试常量文件: // constants.js const MY_CONST_1 = 1; exports.MY_CONST_1 = MY_CONST_1; 。。。
.js
文件,以及一个包含TypeScript使用类型的.d.ts
文件。但是没有:我花了几个小时来解决这个问题(还有RTFMing),结果一事无成
这是我第一次尝试常量文件:
// constants.js
const MY_CONST_1 = 1;
exports.MY_CONST_1 = MY_CONST_1;
。。。以及使用它的JavaScript:
// consumer.js
let constants = require('./constants');
let one = constants.MY_CONST_1;
这很好,但当我尝试在TypeScript中使用显而易见的方法时:
// consumer.ts
import * as constants from './constants';
let one: number = constants.MY_CONST_1;
否:错误TS2307:找不到模块“./constants”。
因此,必须在与constants.js
文件相同的目录中编写一个constants.d.ts
文件,对吗?听起来很容易,但六次不同的尝试都取得了成功。无论我做什么,Typescript都会抱怨错误TS2306:File'/Users/griscom/Documents/Work/test/constants.d.ts'不是模块
那么,一个成功的constants.d.ts
文件是什么样子的呢?或者,如果我必须在constants.js
中进行更改才能使其正常工作,它们会是什么
另外,这是我的tsconfig.json
文件:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"noImplicitReturns": true
}
}
(这似乎是一个简单而明显的需求;过程的不透明性让人沮丧。)选项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;
// constants.d.ts
export const MY_CONST_1: number;
您可以编写一个如下所示的constants.d.ts
文件:
// constants.js
export const MY_CONST_1 = 1;
// constants.d.ts
export const MY_CONST_1: number;
在以前的尝试中,您关闭的地方是使用声明模块
,该声明用于声明外部模块的类型(如来自节点的模块
)。在这种情况下,只需将constants.d.ts
文件放在与constants.js
相同的目录中,并使用export
即可告诉ts,导出该值的是一个js模块:
import { MY_CONST_1 } from "./constants";
import * as constants from "./constants";
需要记住的重要一点是,.d.ts
文件没有对照.js
文件进行检查,以确保它实际上是正确的,这取决于您。因此,如果对.js
文件进行更改,则必须确保相应且正确地更新.d.ts
文件。编译错误或缺少编译错误并不意味着它正确与否。这是allowJs
存在的原因之一,因为它避免了此类泄漏
export const MyConst =1;
或
通常远离模块,因为这与inports中模块的含义不一致。取而代之的是使用“名称空间”,它非常类似于具有静态成员的类。意思是你可能会做(在电话上,不能尝试):
但最后,尽量避免在额外的名称空间和类等中包装东西,因为导入语法是模块。此外,它还使您的代码树形化。另一个选项:使用。事实上,您的常量是全局的,即由于缺少export
关键字,因此未在模块中定义:
import./constants'代码>
与另一个响应中提到的allowJs
编译器选项结合使用。好主意,但是我项目中的所有其他JavaScript文件都会触发错误:“无法写入文件XXXX,因为它会覆盖输入文件”。是的,您需要将源文件与输出文件分开。JS源文件将以最小的转换进行复制(例如,只有ES6到ES5语法)。为什么不呢?或者,编写.d.ts
文件应该可以,您尝试过什么?这是一个很大的现有项目,添加此功能的好处将被更改生成过程的复杂性所抵消。关于.d.ts
文件,我在网上找到了很多示例,但编译器一直在含糊其辞地抱怨。我知道这种感觉,但根据我的经验,这通常更像是一个心理障碍你能把你在问题中尝试过的.d.ts
东西贴出来吗?