简体   繁体   English

打字稿。 我可以区分编译时依赖性和运行时依赖性

[英]Typescript. Can I distinguish between compile-time and run-time dependence

I'm using the CommonJS module conventions, since I'm targeting node.js for testing and using browserify to make a single .js file. 我使用CommonJS模块约定,因为我的目标是进行测试并使用browserify制作单个.js文件的node.js。 Currently my modules are circularly dependent. 目前,我的模块是循环依赖的。 What I'd like to do is to indicate that module value depends on module pnode , but only at compile-time. 我想做的是指示模块value取决于模块pnode ,但仅在编译时。 Ie any run-time dependence should be flagged as an error. 即,任何运行时相关性都应标记为错误。 Eg if module pnode declares a type T, then in module value , I'd like for a declaration like var a : pnode.T to compile without error, but an expression like new pnode.T() or a instanceof pnode.T would be in error because they creates a run-time dependence. 例如,如果模块pnode声明了类型T,那么在模块value ,我希望像var a : pnode.T这样的声明进行编译而不会出错,但是像new pnode.T()a instanceof pnode.T会错误,因为它们创建了运行时依赖项。

Is there a way to do this? 有没有办法做到这一点?

Motivation: Currently pnode and value are circularly dependent. 动机:目前, pnodevalue是循环依赖的。 That's ok as long as there is no circular dependence at run time. 只要运行时没有循环依赖关系就可以。 Circular dependence at run time causes a problem because node.js does not handle it correctly or even warn about it. 在运行时循环依赖会导致问题,因为node.js无法正确处理甚至警告它。 My current code looks like this 我当前的代码如下所示

File pnode.ts 文件pnode.ts

import value = require('./value') ;

module pnode {

    export abstract class Label {
    }
    export class LambdaLabel {
        step() {
            return new value.ClosureV(this) ;
        }
    }
}

export = pnode ;

File value.ts 文件value.ts

import pnode = require('./pnode') ; // Would like to avoid this.

module value {

    export class ClosureV {

        constructor( func : pnode.Label ) {

            if ( func instanceof pnode.Label ) // Would like an error here.
                console.log("a") ; else console.log("b") ;
        }
    }
}

export = value;

What I've tried. 我尝试过的 I was hoping that replacing the line 我希望替换生产线

 import pnode = require('./pnode') ; // Would like to avoid this.

with

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

might do the trick, but it did not. 也许可以解决问题,但事实并非如此。 There are various ways that I have considered eliminating the compile-time circular dependence, so that is my fall-back option. 我曾考虑过多种方法来消除编译时循环依赖,因此这是我的后备选项。

If you compile pnode.ts with the declaration flag you'll get this .d.ts file: 如果使用声明标志编译pnode.ts ,则会得到此.d.ts文件:

declare module pnode {
    abstract class Label {
    }
    class LambdaLabel {
        step(): any;
    }
}
export = pnode;

Then when you reference it: 然后,当您引用它时:

/// <reference path="test.d.ts" />

module value {
    export class ClosureV {
        constructor( func : pnode.Label ) {}
    }
}

You'll get the error you described: Cannot find namespace 'pnode' . 您将得到描述的错误: Cannot find namespace 'pnode'
That's because the compiler knows that this .d.ts file represents a CommonJS module because it ends with export = pnode; 那是因为编译器知道这个.d.ts文件代表一个CommonJS模块,因为它以export = pnode;结尾export = pnode; .

If you remove that line (or comment it out) then the error goes away. 如果删除该行(或将其注释掉),则该错误消失。 You'll need to remove this line after every compilation (or have a script that does it for you) but it will work. 每次编译后,您都需要删除此行(或者有一个脚本可以为您完成此操作),但是它将起作用。

In any case I believe that having a third module which acts as a share module for the others will give you more flexibility, as you'll also be able to have common classes/functions that are available at runtime. 无论如何,我相信拥有第三个模块作为其他模块的共享模块将为您提供更大的灵活性,因为您还可以拥有运行时可用的通用类/函数。
Not to mention that you won't need to take another action after compilation. 更不用说编译后您将无需执行其他操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM