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

时间:2016-07-26 14:07:57

标签: typescript

我使用CommonJS模块约定,因为我定位node.js进行测试并使用browserify制作单个.js文件。目前我的模块是循环相关的。我想做的是表明模块value依赖于模块pnode,但仅限于编译时。即任何运行时依赖都应标记为错误。例如。如果模块pnode声明了类型T,那么在模块value中,我希望像var a : pnode.T这样的声明能够无错误地编译,但像new pnode.T()这样的表达式或a instanceof pnode.T会出错,因为它们会产生运行时依赖性。

有办法做到这一点吗?

动机:目前pnodevalue是循环相关的。只要在运行时没有循环依赖,那就没问题。运行时的循环依赖会导致问题,因为node.js无法正确处理它甚至警告它。我目前的代码看起来像这样

档案pnode.ts

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

module pnode {

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

export = pnode ;

档案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;

我尝试了什么。我希望更换这条线

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

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

可能会成功,但事实并非如此。我考虑过各种方法来消除编译时循环依赖性,因此这是我的后退选项。

1 个答案:

答案 0 :(得分:0)

如果使用声明标志编译pnode.ts,您将获得此.d.ts文件:

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

然后当你引用它时:

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

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

您将收到您所描述的错误:Cannot find namespace 'pnode' 那是因为编译器知道这个.d.ts文件代表一个CommonJS模块,因为它以export = pnode;结尾。

如果删除该行(或将其注释掉),则错误消失。你需要在每次编译后删除这一行(或者有一个为你完成的脚本)但是它会起作用。

在任何情况下,我都认为拥有第三个模块作为其他模块的共享模块将为您提供更大的灵活性,因为您还可以拥有在运行时可用的公共类/功能。
更不用说你不需要在编译后再采取其他行动了。