如何从节点模块导出Typescript接口?

时间:2018-02-14 15:13:59

标签: node.js typescript node-modules rollupjs

搞清楚了!

最初,我试图像这样导入我的模块:

const qml = require('quill-marking-logic')
const { checkSentenceCombining, checkSentenceFragment, checkDiagnosticQuestion, checkFillInTheBlankQuestion, ConceptResult } = qml

因为我在尝试使用

时出现TS2307: Cannot find module 'quill-marking-logic'错误

import { checkSentenceCombining, checkSentenceFragment, checkDiagnosticQuestion, checkFillInTheBlankQuestion, ConceptResult } from 'quill-marking-logic'

这是因为我在导入应用的tsconfig中使用"module": "es6",默认情况下将moduleResolution选项设置为Classic。通过明确地将其设置为node,我能够使用import语法并获取我的界面!

原帖

我使用Typescript构建了一个节点模块,我将其用作另一个应用程序中的依赖项。我在模块中有几个接口,我试图从它的入口点导出,以便我可以在我的其他应用程序中使用它们,但它们在编译后被删除。我知道这是Typescript设计的一部分,因为接口用于运行时分析,但我想知道是否有办法绕过它,所以我不必在我的其他应用程序中再次定义它们并且必须维护两个地方的代码相同。我正在使用汇总作为我的捆绑包。

这就是我的入口点的.d.ts版本:

export { checkSentenceCombining } from './libs/graders/sentence_combining';
export { checkDiagnosticQuestion } from './libs/graders/diagnostic_question';
export { checkSentenceFragment } from './libs/graders/sentence_fragment';
export { checkFillInTheBlankQuestion } from './libs/graders/fill_in_the_blank';
export { Response, PartialResponse, ConceptResult, FocusPoint, IncorrectSequence, FeedbackObject, GradingObject, WordCountChange } from './interfaces/index';

最后一行导出是接口应该通过的地方。

这是我的tsconfig:

{
    "compilerOptions": {
        "target": "es5",
        "module": "CommonJS",
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "sourceMap": false,
        "noImplicitAny": false,
        "lib": [
            "dom",
            "es7"
        ],
        "typeRoots": [
            "node_modules/@types/"
        ],
        "declaration": true
    }
}

这是我正在尝试将其导入到的应用程序的tsconfig:

{
    "compilerOptions": {
        "outDir": "./dist/",        // path to output directory
        "sourceMap": true,          // allow sourcemap support
        "strictNullChecks": true,   // enable strict null checks as a best practice
        "module": "es6",            // specifiy module code generation
        "jsx": "react",             // use typescript to transpile jsx to js
        "target": "es6",            // specify ECMAScript target version
        "allowJs": true,            // allow a partial TypeScript and JavaScript codebase
        "lib": ["ES2017", "DOM"],            //
        "allowSyntheticDefaultImports": true // Allow import React from 'react'
    }
}

我指向package.json中“typings”键中生成的.d.ts文件。

3 个答案:

答案 0 :(得分:2)

是的,这是可能的。为此,export您想要在模块的入口点文件中为模块的使用者提供的接口:

// in entry.ts
import { MyInterface1 } from '/path/to/interface/one';
import { MyInterface2 } from '/path/to/interface/two';

export { MyInterface1, MyInterface2 };

然后,在使用此模块的代码中,您可以执行以下操作:

import { MyInterface1, MyInterface2 } from 'my-module`;

为了使其正常工作,您需要确保模块中declaration编译器选项设置为true - 这会导致编译器输出.d.ts文件包含模块的输入信息。

最后一个难题是在模块的“package.json”中包含types属性,该属性指向此.d.ts文件:

{
    "name": "my-module",
    "main": "./entry.js",
    "types": "./my-module.d.ts"
}

有关准备发布模块的更多信息: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

答案 1 :(得分:0)

您应该使用--declaration选项为您的模块生成d.ts个文件。定义文件将包含导出的接口,您可以在应用程序中使用它们。

您应该将定义文件与模块一起包含在位置打字稿中查找定义in

  

类似地,非相对导入将遵循Node.js解析逻辑,首先查找文件,然后查找适用的文件夹。所以从" moduleB"导入{b};在源文件/root/src/moduleA.ts中将导致以下查找:

/root/src/node_modules/moduleB.ts
/root/src/node_modules/moduleB.tsx
/root/src/node_modules/moduleB.d.ts
/root/src/node_modules/moduleB/package.json (if it specifies a "types" property)
/root/src/node_modules/moduleB/index.ts
/root/src/node_modules/moduleB/index.tsx
/root/src/node_modules/moduleB/index.d.ts 

答案 2 :(得分:0)

将此添加到您的tsconfig.json文件中:

"allowJs": false,
"declaration": true,

将此添加到您的package.json文件中:

"types": "dist/index.d.ts",

此外,不要忘记将d.ts文件放在您在package.json中发布的单独文件夹中,否则它们将会丢失。例如,将它们放在typings文件夹旁边的src文件夹中,然后将其添加到package.json

  "files": [
    "/dist",
    "/typings"
  ],

有关更多详细信息:https://medium.com/cameron-nokes/the-30-second-guide-to-publishing-a-typescript-package-to-npm-89d93ff7bccd