打字稿迁移:具有多个对象的Javascript“命名空间”

时间:2018-11-08 12:36:03

标签: javascript typescript

我正在将一些旧的js迁移到ts。该文件具有格式(为清晰起见,省略了功能实现):

// component.js
const Component = {}; // 'namespace' for components
Component.Base = function() {}
Component.A = function() {} // extends Base
Component.A.prototype.doStuffA = function() {}
Component.B = function() {} // extends Base
Component.B.prototype.doStuffB = function() {}
Component.C = function() {} // extends Base
// ... 100 other components, 2000 lines of code
export default Component;

在js中,我可以执行以下操作:

import Component from './component';
// 1. Instantiate one component
const compA = new Component.A();
// 2. or create multiple components 
const threeComps = ['A', 'B', 'C'].map(name => new Component[name]() );

但是在ts中,我什至无法实例化一个组件:

import Component from './component';
const compA: Component.A = new Component.A();
// tsc Cannot find namespace 'Component'

问题:什么是将component.js转换为有效打字稿的(快速)方法,最好保持尽可能多的类型检查,例如

const compA: Component.A = new Component.B()

会被编译器标记为错误。

我尝试将以下内容附加到文件末尾:

namespace Component {
    interface A {};
    interface B {};
    interface C {};
}

这似乎可以编译成正确的javascript,但是我必须将所有属性添加到接口中。似乎很乏味并且违反了DRY原则。

1 个答案:

答案 0 :(得分:0)

如果您要迁移到TypeScript,则可以立即利用component.ts文件中的类语法:

export class Base {

}

export class A {
    doStuffA() {}
}

export class B {
    doStuffB() {}
}

export class C extends Base {

}

您可以使用导入别名来使用它:

import * as Component from './component';

const a = new Component.A();

或者您可以选择导入什么:

import { A } from './component';

const a = new A();

导出默认设置/模块与命名空间混合

总的来说,专家们说export default is a bad thing和那个you shouldn't mix modules and namespaces

如果需要,您可以这样做。这是带有名称空间/默认值的示例:

namespace Component {
    export class Base {

    }

    export class A {
        doStuffA() {}
    }

    export class B {
        doStuffB() {}
    }

    export class C extends Base {

    }
}

export default Component;

以及用途:

import Component from './component';

const a = new Component.A();