Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
559 views
in Technique[技术] by (71.8m points)

typescript - How do I re-export an imported module that has interfaces in it in a usable manner?

I had one file with a large number of modules in it. I wanted to separate those modules into different files and expose them from the original file. This is because the original file is >800 loc and becoming very difficult to manage.

So I have created a file that contains a module with functions and interfaces:

export module Subsection1 {
    
    export interface Interface {
        id: string;
    }
    
    export function DoInterfaceStuff(obj: any) {
        return = <Interface>{ id: obj }
    }
}

I have the


import { Subsection1 as Subsection1Base } from "./Subsection1";


export module GodManager {

    export type Subsection1 = Subsection1Base & (typeof Subsection1Base);
    export var Subsection1 = Subsection1Base;

    var ObjByID = new Map<string, Subsection1.Interface>();
    export function DoThing(source) {
        ObjByID.set(source.id, Subsection1.DoInterfaceStuff(source.origin));
    }
}

NOTE The new name and variable must be accessible externally to the current class because I'm actually loading Subsection1Base lazily (mostly to avoid a circular dependancy).

question from:https://stackoverflow.com/questions/65879719/how-do-i-re-export-an-imported-module-that-has-interfaces-in-it-in-a-usable-mann

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Respectfully, don't do that; don't reuse names of types (or interfaces, namespaces, classes, etc.) for other things. You are going to drive yourself (and others) nuts trying to figure out what you are referencing.

If we clean up the naming of your types, we can figure out pretty quickly what's wrong here.

In TriggerEvent, we rename the interface Trigger to ITrigger:

export interface ITrigger {
    // ..
}

export module Trigger {
    //...
    
    export function Serialise(restoredEvent: ITrigger) {
        //...
    }
}

Now, in ActionManager, we can see what went wrong:

import { Trigger as TriggerBase } from "./TriggerEvent";

export module ActionManager {

    type Trigger = TriggerBase & (typeof Trigger); 
    //             ^^^^^^^^^^^
    // ERROR - Cannot use namespace 'TriggerBase' as a type.
    var Trigger = TriggerBase;

    var EventsByID = new Map<UUID, Trigger>();
    var PrepreparedInputs = new Map<UUID, Trigger.Serialised>(); 
    //                                    ^^^^^^^ 
    // ERROR - 'Trigger' only refers to a type, but is being used as a namespace here.
}

You cannot use a namespace (module) as a type. (see the docs). Before, since the interface and the module were named the same, TypeScript went with the context-appropriate option, the interface. Ergo, no errors there! Regardless, we still have the original error 'Trigger' only refers to a type... because a type is a type, and not a namespace (or module).

Finally, ActionManager.Trigger.Serialise(stuff); isn't working because Trigger isn't exported from the ActionManager module.

Solution

Since you can't assign a module to a type, reference the module directly in your PreparedInputs:

    var PrepreparedInputs = new Map<UUID, TriggerBase.Serialised>(); 

And, as you did with TriggerEvent, export what types/variables you want to use outside a module:

// The interface was renamed to ITrigger in TriggerEvent.
import { Trigger as TriggerBase, ITrigger } from "./TriggerEvent"; 

export module ActionManager {
    export var Trigger = TriggerBase;

    export var EventsByID = new Map<UUID, ITrigger>();
    export var PrepreparedInputs = new Map<UUID, TriggerBase.Serialised>(); 
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...