在Node.js中混合使用JavaScript和TypeScript

在Node.js中混合使用JavaScript和TypeScript,javascript,node.js,typescript,jsdoc,Javascript,Node.js,Typescript,Jsdoc,虽然在普通ES6中有Node.js的一部分,但是否可以在同一个项目中混合使用某些Typescript模块 例如,在TypeScript中定义一些类型,这些类型通过require导入普通ES6文件?是的,这是可能的 组合以下TypeScript编译器选项 --allowJs 显式支持混合JavaScript和类型脚本源 --outDir 由于所有文件都将被传输,因此有必要将生成的JavaScript输出到不同的目录中,否则将导致输入错误 .js文件将被覆盖1 --checkJs 这是完全可选的

虽然在普通ES6中有Node.js的一部分,但是否可以在同一个项目中混合使用某些Typescript模块

例如,在TypeScript中定义一些类型,这些类型通过
require
导入普通ES6文件?

是的,这是可能的

组合以下TypeScript编译器选项

  • --allowJs

    显式支持混合JavaScript和类型脚本源

  • --outDir

  • 由于所有文件都将被传输,因此有必要将生成的JavaScript输出到不同的目录中,否则将导致输入错误
    .js
    文件将被覆盖1

  • --checkJs
  • 这是完全可选的。如果指定,编译器将对JavaScript文件进行类型检查,报告错误,就像在TypeScript文件中一样,否则它将容忍不一致

    至于在JavaScript文件中使用TypeScript文件中声明的类型,这确实可以做到

    TypeScript实际上支持VisualStudio代码等工具中的所有JavaScript intellisense

    类型可以放在JSDoc2注释中。这些注释可以引用从TypeScript(
    .ts
    /
    .tsx
    /
    .d.ts
    )文件导入的类型。像VisualStudio代码这样的IDE将在这些注释中提供语法高亮显示和自动完成

    但是有一个警告。因为JavaScript中没有类型的清单语法,所以不能单独导入它们,但必须附加到导入的值。这可以通过TypeScript的声明合并实现,如下所示

    例如:

    a.ts

    export default createThing;
    
    function createThing(...args): createThing.Thing  {...}
    
    namespace createThing {
      export interface Thing {...}
    }
    
    import createThing from './a';
    
    /**
     * @param {createThing.Thing} thing
     */
    export function takesThing(thing) {}
    
    b.js

    export default createThing;
    
    function createThing(...args): createThing.Thing  {...}
    
    namespace createThing {
      export interface Thing {...}
    }
    
    import createThing from './a';
    
    /**
     * @param {createThing.Thing} thing
     */
    export function takesThing(thing) {}
    
    注意事项:

    1
    --outDir
    如果您另外指定了
    --noEmit
    标志,则不需要。您可以在使用(with)或(with)等工具托管TypeScript transpiler时执行此操作。如果您正在使用,同样适用

    2:虽然称为注释,但它们是在TypeScript类型系统的上下文中解释的,而不是在JSDoc系统的上下文中解释的。像TypeScript和Google这样的语言和工具,为了自己的目的,有效地劫持了JSDoc语法,从而给它的结构赋予了潜在的冲突含义。这通常不是问题,但值得知道,因为很难确定这些注释的适用性和正确性以及它们引用或声明的类型的兼容性

    备注:

    尽管这个问题和答案都是关于导入JavaScript文件中使用的类型的,但这通常是不必要的,因为编译器将从表达式的值推断类型


    还值得一提的是,如果您发现自己需要编写大量JSDoc样式的类型注释,那么几乎可以肯定,最好将文件转换为TypeScript,因为JSDoc中表示类型的语法很笨拙。多亏了
    --allowJs
    选项,您可以按上述方式逐个文件执行此操作。

    不,它们需要编译为JavaScript。在编译之前,TypeScript(不一定)在语法上是有效的JS。谢谢,这似乎是可行的。我可以在
    b.js
    中混合
    require()
    import
    吗?@AlexanderZeitler混合
    import
    require
    是正交的-它会像你说的那样工作。您是否可以使用
    require
    ,取决于您指定的模块格式(
    --module
    )。如果指定了
    system
    es2015
    ,则不能使用
    require
    ,因为这些格式不提供它。如果指定了
    amd
    commonjs
    umd
    ,则可以使用它。不过,把它们混在一起是个坏主意。谢谢你的解释。目前,混合只是出于迁移目的。迁移不需要混合,因为导入将被传输。