【问题标题】:How do I reference a Typescript enum inside a definition file如何在定义文件中引用 Typescript 枚举
【发布时间】:2014-11-21 18:42:22
【问题描述】:

我正在使用安装了更新 4 和 Typescript 1.3 的 Visual Studio 2013。

如果我有一个打字稿文件,像这样:

MyEnums.ts:

export = MyEnumModule;
module MyEnumModule {
    export enum AnEnum { RED, BLUE, GREEN }
}

我有一个像这样的定义文件:

我的定义.d.ts:

declare module MyDefinitions {
    interface ISomeInterface {
        aProperty: string;
        aMethod: () => void;
        aColor: MyEnumModule.AnEnum;
    }
}

我基本上收到“找不到名称'MyEnumModule'”的错误

当从打字稿文件中引用时,这个枚举文件可以正常工作。例如:

SomeCode.ts:

export = MyCode;

import MyEnums = require('MyEnums');

module MyCode{

    export class MyClass implements ISomeInterface {
        public aColor: MyEnums.AnEnum = MyEnums.AnEnum.RED;
        ...and so on

我的理解是,添加 /// <reference ... 或导入都不适用于 .d.ts 文件(我只是想确定一下,但无论哪种方式似乎都不起作用)。

有谁知道如何在这样的定义文件中引用枚举?

提前致谢。

--更新:

这是我在尝试下面的史蒂夫芬顿建议后看到的错误(使用我刚刚制作的示例项目)。

MyDefinitions.ts

import MyEnumModule = require('../App/MyEnums');

declare module MyDefinitions {
    interface ISomeInterface {
        aProperty: string;
        aMethod: () => void;
        aColor: MyEnumModule.AnEnum;
    }
}

MyEnums.ts

export = MyEnumModule;

module MyEnumModule {
    export enum AnEnum { RED, BLUE, GREEN }
}

MyClass.ts

export = MyCode;
import MyImport = require('MyEnums');
module MyCode {
    export class MyClass implements MyDefinitions.ISomeInterface {
        public aColor: MyImport.AnEnum = MyImport.AnEnum.RED;
        constructor() { }
        aProperty: string = "";
        aMethod: () => void = null;       
}

}

文件夹结构
应用

  • -MyClass.ts
  • -MyEnums.ts

  • 定义
  • -MyDefintions.d.ts
  • MyClass.ts 内部 MyDefinitions.ISomeInterface 带有红色下划线,并带有悬停警告“找不到名称 MyDefinitions”。

    我为该项目设置了 AMD

    【问题讨论】:

    • 只要您使用的是 Visual Studio 2013 并且 d.ts 与您的 .ts 文件在同一个项目中,您就不需要在文件本身中包含任何内容。确保它们在同一个模块中,但首先作为测试以确保其正常工作
    • 谢谢,我已经为 AMD 设置了 Web 应用程序项目的模块系统。枚举文件和定义文件位于不同的文件夹中。定义文件目前被用作保存整个项目中文件使用的引用的公共点。我认为使用 AMD 时模块名称不重要?
    • 我很久没有使用 AMD 所以不记得这些天它是如何导入的所以不确定。我确实知道使用 VS,您不再需要包含 /// references,这很好。我会尝试使用相同的模块来让它工作,然后担心让它与 AMD 一起工作

    标签: visual-studio-2013 enums requirejs typescript amd


    【解决方案1】:

    有谁知道如何在这样的定义文件中引用枚举?

    正如 Steve Fenton 所指出的,有一些解决方法,但系统并非为此而设计。您应该在定义文件中引用其他定义文件,而不是在定义文件中引用*实现文件* (MyEnum.ts)。

    【讨论】:

    • 我倾向于这个,定义不应该引用实现是有道理的。我想了想,意识到我专注于“如何”而不是“我应该”。一个同事制作了 d.ts 文件,一开始我并没有质疑其有效性,但我只是把它变成了一个 .ts (我觉得 d.ts 主要是为现有的 js 提供打字?)和它工作得很好。我仍然对类型文件如何指定枚举类型感到困惑?
    【解决方案2】:

    我对此进行了检查,以下定义适用于我,尽管我必须承认我从未从“定义”代码中引用过“实际”代码 - 但我想不出任何理由不这样做。

    import MyEnumModule = require('MyEnumModule');
    
    declare module MyDefinitions {
        interface ISomeInterface {
            aProperty: string;
            aMethod: () => void;
            aColor: MyEnumModule.AnEnum;
        }
    } 
    

    关于混合定义和实际实现...

    TypeScript 中的类型系统是一种设计时和编译时工具。当在设计时构造类型信息时,类型信息是从实现代码中推断出来的、从装饰实现的注释中获取的还是来自环境声明的,都没有区别。

    有许多混合实现代码和环境声明的用例 - 如果您将一个百万行的 JavaScript 程序迁移到 TypeScript,您可能无法将它从最底层的依赖项向上迁移。此外,您可以将环境声明放在普通文件中 - 不仅仅是定义文件 - 如果您有一个大型程序,您甚至可能不知道放置在环境声明中的类型是“真实的”还是“环境的”。

    实现代码类型和环境声明类型之间的唯一区别在于,类型信息紧挨着实际代码文件中的实现,而环境声明则位于单独的文件中。

    所以...如果您在环境声明中使用实际实现的类型时遇到问题,这很可能是由可以修复的某些问题引起的。我在上面提供的示例适用于我在 Visual Studio 2013 Update 4 中的一个项目 - 使用 TypeScript 构建配置设置来编译 AMD 模块。如果您可以分享问题的确切细节,我很乐意帮助您解决问题。

    话虽如此 - 如果您正在为少量代码创建类型定义,将它们粘贴到 .ts 文件甚至可能比编写定义更快 - 因此您应该根据具体情况决定在哪里付出努力。

    【讨论】:

    • 我试过这个,但它导致代码文件无法找到定义(就像导入导致一些问题一样)。我猜巴萨拉特是对的,但你也指出了那个方向。
    • 我已经更新了关于您不能混合实现和声明代码的建议的答案,因为我无法将其放入评论中:)
    • 谢谢,这是很好的信息。我用一些额外的细节更新了我的 OP。
    • 修复该问题的两个更改... 1. 在 MyDefinitions export = MyDefinitions; 和 2. 在 MyClass import MyDefinitions = require('MyDefinitions');
    • 错过了,谢谢!不得不使用 import MyDefinitions = require('../Definitions/MyDefinitions');,但在那之后它工作得很好。在过去的 10 年里,我主要是 C#,猜 typescript 让我的大脑嘎嘎作响 :)
    猜你喜欢
    • 2015-07-02
    • 2016-10-28
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多