使用自定义const枚举的Typescript定义

时间:2017-01-06 22:36:38

标签: typescript commonjs typescript-typings

我正在尝试为库创建TypeScript定义文件。

库有一个方法接受number类型的参数,但该参数只能是一组特定的数字,所以我想让我的定义说它需要一个我使用a创建的枚举类型const enum

但是,当我在.d.ts中定义我的课程时,就像这样:

// definitions/SimpleDefinition.d.ts

/// <reference path="Enums.ts" />

declare class SampleDefinedClass {
    public static SampleMethod(enumArg: Enums.SampleEnum): void;
}

我的枚举是这样的:

// definitions/Enums.ts

export const enum SampleEnum {
    Item1 = 1,
    Item2 = 2
}

我有index.d.ts将2连在一起:

// definitions/index.d.ts

/// <reference path="Enums.ts" />
/// <reference path="SampleDefinition.d.ts" />

编译器告诉我:

../definitions/SampleDefinition.d.ts(4,41): error TS2503: Cannot find namespace 'Enums'.

我尝试在SampleDefinition.d.ts的顶部添加导入,但导致我的代码文件中无法正确识别定义。虽然Visual Studio和Visual Studio代码不会在实际导入时显示错误。

import Enums = require("./Enums");

Main.ts(6,1): error TS2304: Cannot find name 'SampleDefinedClass'.

我已经尝试了更多的东西,比如使用AMD,移动文件,但似乎无法让它工作。有没有办法做到这一点?或者我必须找到另一种方法来做/放弃?

我用这个确切的样本创建了一个GitHub repo

2 个答案:

答案 0 :(得分:2)

您的SampleDefinition.d.ts没有顶级导入或导出,Enum.ts也没有。也就是说,Enums是一个模块,而SampleDefinition则不是,但您尝试在其中使用Enums。使用较旧(过时)的术语,SampleDefinition.d.ts是内部模块,Enums是外部模块,您无法在一个应用程序中混合使用。

有两种方法可以使它们保持一致:

单向是将所有内容设为内部,而不在顶层导入/导出:

修正Enum.ts:将export包裹在namespace

namespace Enums {
    export const enum SampleEnum {
        Item1 = 1,
        Item2 = 2
    }
}

已修复Main.ts - 只需删除import Enums ..

即可
/// <reference path="../definitions/index.d.ts" />

console.log(Enums.SampleEnum.Item2);
SampleDefinedClass.SampleMethod(Enums.SampleEnum.Item1);

另一种方式是将所有内容都变成模块:

已修复SampleDefinition.ts:使用import代替referenceexport类而非声明:

import Enums = require("./Enums");


export class SampleDefinedClass {
    public static SampleMethod(enumArg: Enums.SampleEnum): void;
}

修复Main.ts:再次import明确而不是reference。这样,您根本不需要definitions/index.d.ts

import Enums = require("../definitions/Enums");
import {SampleDefinedClass} from "../definitions/SampleDefinition"


console.log(Enums.SampleEnum.Item2);
SampleDefinedClass.SampleMethod(Enums.SampleEnum.Item1);

选择哪种方式取决于您。主要区别在于,对于模块,您的应用程序将在运行时需要模块加载器。没有模块,它可以编译成一个组合的脚本文件。这主要适用于浏览器(您必须自己提供模块加载器),为节点编译的模块化代码将使用require并且可以正常工作。

答案 1 :(得分:0)

在定义文件中,您必须使用declare导出枚举。

我查看了DefinitelyTyped中的一些示例,这里有一个:

export declare enum EDeflateStrategy {
    DEFAULT_STRATEGY = 0,
    FILTERED = 1,
    HUFFMAN_ONLY = 2,
    RLE = 3,
    FIXED = 4,
}

您的代码的问题在于您的定义文件似乎在查看.ts文件而不是另一个.d.ts文件。

如果这是你的图书馆并且是用ts编写的,你可以添加

"declaration": true
在你的tsconfig.json文件上

,让tsc为你生成定义。

如果不是,您可以尝试在ts中模拟此库中的内容,并让tsc通过启用此选项为您生成声明。