While responding to a question about creating a new type, I suggested that a module could be used as the data-structure. To type check a given expression against the new data-structure, one can use
type( some_expr, '`module`'( 'export1', 'export2' ))
where export1 and export2 are exports of the module. That technique, however, is not robust in that any module with those exports (and possibly others) matches the type. While that may not be a concern, there is a way to uniquely type check a constructed module: give it an export equal to a local value. Here is a demonstration of the technique:
demo := module()

export New;
local ModuleLoad, NuTypeID;

    ModuleLoad := proc()
        TypeTools:-AddType('NuType', x -> type(x, '`module`'('ID')) and x:-ID = NuTypeID );
    end proc;

    New := proc()
        export ID;
            ID := NuTypeID;
        end module;
    end proc;


end module:
The export 'ID' is added to the constructed module (in the demo it is the only export); it is assigned NuTypeID, a variable local to the demo package, by the constructor New. The NuType type, created via a call to TypeTools[AddType], returns true if its argument is a module that exports 'ID' and whose value equals NuTypeID.
> m1 := demo:-New():
> type( m1, NuType );

Please Wait...