在 Node.js 中混合使用 JavaScript 和 TypeScript
Mixing JavaScript and TypeScript in Node.js
虽然在纯 ES6 中有 Node.js 的一部分,但是否可以在同一项目中混合使用某些 Typescript 模块?
例如在 TypeScript 中定义了一些通过 require
导入普通 ES6 文件的类型?
是的,这是可能的。
结合以下 TypeScript 编译器选项
--allowJs
明确支持混合 JavaScript 和 TypeScript 来源
--outDir
由于所有文件都将被转译,因此有必要将结果 JavaScript 输出到不同的目录,否则输入
.js
个文件将被覆盖1.
--checkJs
这完全是可选的。如果指定,编译器将对 JavaScript 文件进行类型检查,报告错误,就像在 TypeScript 文件中一样,否则它会容忍不一致。
至于在JavaScript文件中使用TypeScript文件中声明的类型,确实可以做到。
TypeScript 实际上为 Visual Studio 代码等工具中的所有 JavaScript 智能感知提供支持。
类型可以放在 JSDoc2 注释中。这些注释可以引用从 TypeScript (.ts
/.tsx
/.d.ts
) 文件导入的类型。 Visual Studio 代码等 IDE 将在这些注释中提供 syntax-highlighting 和自动完成功能。
但是有一个警告。因为 JavaScript 中的类型没有明显的语法,它们不能单独导入,但必须附加到导入的 value。这可以通过 TypeScript 的声明合并最方便地实现,如下所示。
示例:
a.ts
export default createThing;
function createThing(...args): createThing.Thing {...}
namespace createThing {
export interface Thing {...}
}
b.js
import createThing from './a';
/**
* @param {createThing.Thing} thing
*/
export function takesThing(thing) {}
备注:
1:如果另外指定 --noEmit
标志,则不需要 --outDir
。当使用诸如 SystemJS (with plugin-typescript) or Webpack (with ts-loader) to host the TypeScript transpiler. The same applies if you are using TS Node.
之类的工具时,您会这样做
2:尽管被称为 JSDoc comments, they are interpreted in the context of the TypeScript type system, not the JSDoc system. Languages and tools like TypeScript, and Google's Closure Compiler,但为了自己的目的有效地劫持了 JSDoc 语法,从而为其构造赋予了潜在的冲突含义。这通常不是问题,但值得了解,因为很难确定这些注释的适用性和正确性以及它们引用或声明的类型的兼容性。
备注:
虽然这个问题和答案都是关于导入类型以在 JavaScript 文件中使用的,但它通常是不必要的,因为编译器会根据您的表达式的值推断类型。
还值得一提的是,如果您发现自己需要编写大量 JSDoc 样式的类型注释,那么几乎可以肯定,将文件转换为 TypeScript 会更好,因为在 JSDoc 中表达类型的语法很笨拙。多亏了 --allowJs
选项,您可以逐个文件执行此操作,如上所述。
虽然在纯 ES6 中有 Node.js 的一部分,但是否可以在同一项目中混合使用某些 Typescript 模块?
例如在 TypeScript 中定义了一些通过 require
导入普通 ES6 文件的类型?
是的,这是可能的。
结合以下 TypeScript 编译器选项
--allowJs
明确支持混合 JavaScript 和 TypeScript 来源
--outDir
由于所有文件都将被转译,因此有必要将结果 JavaScript 输出到不同的目录,否则输入
.js
个文件将被覆盖1.
--checkJs
这完全是可选的。如果指定,编译器将对 JavaScript 文件进行类型检查,报告错误,就像在 TypeScript 文件中一样,否则它会容忍不一致。
至于在JavaScript文件中使用TypeScript文件中声明的类型,确实可以做到。
TypeScript 实际上为 Visual Studio 代码等工具中的所有 JavaScript 智能感知提供支持。
类型可以放在 JSDoc2 注释中。这些注释可以引用从 TypeScript (.ts
/.tsx
/.d.ts
) 文件导入的类型。 Visual Studio 代码等 IDE 将在这些注释中提供 syntax-highlighting 和自动完成功能。
但是有一个警告。因为 JavaScript 中的类型没有明显的语法,它们不能单独导入,但必须附加到导入的 value。这可以通过 TypeScript 的声明合并最方便地实现,如下所示。
示例:
a.ts
export default createThing;
function createThing(...args): createThing.Thing {...}
namespace createThing {
export interface Thing {...}
}
b.js
import createThing from './a';
/**
* @param {createThing.Thing} thing
*/
export function takesThing(thing) {}
备注:
1:如果另外指定 --noEmit
标志,则不需要 --outDir
。当使用诸如 SystemJS (with plugin-typescript) or Webpack (with ts-loader) to host the TypeScript transpiler. The same applies if you are using TS Node.
2:尽管被称为 JSDoc comments, they are interpreted in the context of the TypeScript type system, not the JSDoc system. Languages and tools like TypeScript, and Google's Closure Compiler,但为了自己的目的有效地劫持了 JSDoc 语法,从而为其构造赋予了潜在的冲突含义。这通常不是问题,但值得了解,因为很难确定这些注释的适用性和正确性以及它们引用或声明的类型的兼容性。
备注:
虽然这个问题和答案都是关于导入类型以在 JavaScript 文件中使用的,但它通常是不必要的,因为编译器会根据您的表达式的值推断类型。
还值得一提的是,如果您发现自己需要编写大量 JSDoc 样式的类型注释,那么几乎可以肯定,将文件转换为 TypeScript 会更好,因为在 JSDoc 中表达类型的语法很笨拙。多亏了 --allowJs
选项,您可以逐个文件执行此操作,如上所述。