节点模块打字稿类实例类型检查

时间:2019-06-03 12:38:26

标签: typescript node-modules

目前,我的任务是从Vanilla JS创建节点模块并将其移至打字稿。我将它们重写为类,添加了一些功能,编写了旧式包装和相应的Web Pack配置。问题是这些模块中的某些模块是单例的,因此,我们不是要默认导出类,而是要默认导出类实例。问题是我没有使类型检查正常工作:

import DebugJs from 'debug';
const test = (test: DebugJs) => {
    test.console('warn', 'does', 'respond', 'with a warning', test);
};

这里的问题是DebugJs不被识别为类型。因此,目前我必须导入其他接口才能正确设置类型。

为了比较,这是我目前所做的:

import DebugJs, { DebugJsInterface } from 'debug';
const test = (test: DebugJsInterface) => {
    test.console('warn', 'does', 'respond', 'with a warning', test);
};

我尝试过使用命名空间和模块声明,但是老实说,作为一个完全不熟悉节点模块创建并且不熟悉打字稿的人,我真的不知道我在做什么。

这是我当前的index.d.ts文件设置

import DebugJs from './src/debugJsModule';
import {DebugLevels} from "./src/types/types";

export interface DebugJsInterface {
    levels:DebugLevels;
    enabled:boolean;
    level:number;
    console(...arguments: any): void;
    enableDebug(): void;
    disableDebug(): void;
    setLevel(level:number): void;
}

export interface Module {
    DebugJs: DebugJsInterface;
}

export default DebugJs;
declare module 'debug';

在这里,DebugJsInterface被定义为解决方法。我还感到有些困惑,因为我认为idnex.d.ts应该只包含类型信息。但是,如果我不从此处导出类实例,则模块导入将无法正确识别为类。

这是我的debugJsModule包装器,它返回一个类实例:

import DebugJs from './class/DebugJs';
import { DebugLevels } from 'debug/src/types/types';

const DebugJsInstance: DebugJs = new DebugJs();

export default DebugJsInstance;

该类本身被简单地定义为一个类,并且也将其导出为默认导出

 class DebugJs { ... } 

为了清楚起见,从功能上讲一切正常,我只想弄清楚如何通过使用相同的导入名称(在这种情况下为DebugJs)来拥有适当类型的importet类实例,而不必依赖于其他方法importet界面作为解决方法。

2 个答案:

答案 0 :(得分:1)

我现在不知道这种模式是否适合您,但是我通常通过将类和单例放在同一个文件中,然后将单例导出为默认值并将类导出为命名的导出方法来实现:

wp-admin

然后在客户端中导入单例:

The theme directory "theme" does not exist. 

而且,如果您需要与单例无关的class DebugJs { // code } const debug = new DebugJs(); export default debug; export {DebugJs}; 的新实例,则可以:

import debug from '.../path';

debug.format().log().whatever(); // typings and intellisense works fine. debug will be recognised as DebugJs instance.

我很确定这会起作用,因为我经常使用这种模式。

但是,我不知道为什么您的设置无法正常工作。我不知道是否对类型使用默认导出,或者将其与单例重新导出结合使用可能会导致您的问题。

答案 1 :(得分:1)

此代码段实际上没有太大意义:

import DebugJs from 'debug';
const test = (test: DebugJs) => {
    test.console('warn', 'does', 'respond', 'with a warning', test);
};

在这里,您不是要输入DebugJs的实例,而是要告诉打字稿期望an instance of an instance of DebugJs

事情是,我认为这里没有任何意义。为什么要导入某事物的实例然后立即不使用它?

无论如何,可能只需要使用以下语法:

const test = (test: typeof DebugJs) => {
    test.console('warn', 'does', 'respond', 'with a warning', test);
};

您可能会想要:

  1. 不导入实例,而仅导入 导入DebugJsInterface。那就是您应该使用的类型防护。
  2. 或者:不需要将其作为参数。

示例1:

const test = (test: DebugJsInterface) => {
    test.console('warn', 'does', 'respond', 'with a warning', test);
};

示例2:

const test = () => {
    DebugJs.console('warn', 'does', 'respond', 'with a warning', test);
};

我怀疑您想要以上其中之一