tscore.js
function addModuleMember(member, moduleObject, qname) {
	current_node = member;
	var topLevel = qname === '';
    if (member instanceof TypeScript.FunctionDeclaration) {
    	var obj = moduleObject.getMember(member.name.text())
    	if (obj instanceof TObject) {
    		obj.calls.push(parseFunctionType(member))
    	} else {
    		throw new TypeError(member.name.text() + " is not a function")
    	}
    }
    else if (member instanceof TypeScript.VariableStatement) {
        member.declaration.declarators.members.forEach(function(decl) {
            moduleObject.setMember(decl.id.text(), parseType(decl.typeExpr))
        })
    }
    else if (member instanceof TypeScript.ModuleDeclaration) {
    	var name = member.name.text()
    	if (member.isEnum()) { // enums are ModuleDeclarations in the AST, but they are semantically quite different
    		var enumObj = moduleObject.getModule(name)
            enumObj.meta.isEnum = true
    		var enumResult = parseEnum(member, enumObj, qname)
    		moduleObject.types.push(name, enumResult.enum)
    	} else {
            if (name[0] === '"' || name[0] === "'") { // external module?
                parseExternModule(member)
            } else {
                var submodule = moduleObject.getModule(name)
                parseModule(member, submodule, qualify(qname, name))    
            }
    	}
    }
    else if (member instanceof TypeScript.ClassDeclaration) {
    	var name = member.name.text()
    	var clazzObj = moduleObject.getModule(name)
        var clazz = parseClass(member, clazzObj, qname)
        // moduleObject.setMember(member.name.text(), clazz.constructorType)
        moduleObject.types.push(member.name.text(), clazz.instanceType)
    }
    else if (member instanceof TypeScript.InterfaceDeclaration) {
    	var name = member.name.text()
        var t = parseInterface(member, qname)
        moduleObject.types.push(name, t)
    }
    else if (member instanceof TypeScript.ImportDeclaration) {
        var ref = parseType(member.alias)
        if (topLevel || TypeScript.hasFlag(member.getVarFlags(), TypeScript.VariableFlags.Exported)) {
            moduleObject.types.push(member.id.text(), ref)
        } else {
        	// private alias to (potentially) publicly visible type
        	current_scope.env.push(member.id.text(), ref) 
        }
    }
    else if (member instanceof TypeScript.ExportAssignment) {
    	// XXX: I think we can actually just ignore these in the tscheck project,
    	// but for completeness, maybe we should export this information somehow
    	// For reference, this is what I *think* happens:
    	// 		declare module "foo" { export = X }
    	// This means import("foo") will return the value in global variable X.
    	// Maybe we need these for modular analysis?
    }
    else {
    	throw new TypeError("Unexpected member in module " + qname + ": " + member.constructor.name)
    }
}
function addModuleMember(member, moduleObject, qname) {
	current_node = member;
	var topLevel = qname === '';
    if (member instanceof TypeScript.FunctionDeclaration) {
    	var obj = moduleObject.getMember(member.name.text())
    	if (obj instanceof TObject) {
    		obj.calls.push(parseFunctionType(member))
    	} else {
    		throw new TypeError(member.name.text() + " is not a function")
    	}
    }
    else if (member instanceof TypeScript.VariableStatement) {
        member.declaration.declarators.members.forEach(function(decl) {
            moduleObject.setMember(decl.id.text(), parseType(decl.typeExpr))
        })
    }
    else if (member instanceof TypeScript.ModuleDeclaration) {
    	var name = member.name.text()
    	if (member.isEnum()) { // enums are ModuleDeclarations in the AST, but they are semantically quite different
    		var enumObj = moduleObject.getModule(name)
            enumObj.meta.isEnum = true
    		var enumResult = parseEnum(member, enumObj, qname)
    		moduleObject.types.push(name, enumResult.enum)
    	} else {
            if (name[0] === '"' || name[0] === "'") { // external module?
                parseExternModule(member)
            } else {
                var submodule = moduleObject.getModule(name)
                parseModule(member, submodule, qualify(qname, name))    
            }
    	}
    }
    else if (member instanceof TypeScript.ClassDeclaration) {
    	var name = member.name.text()
    	var clazzObj = moduleObject.getModule(name)
        var clazz = parseClass(member, clazzObj, qname)
        // moduleObject.setMember(member.name.text(), clazz.constructorType)
        moduleObject.types.push(member.name.text(), clazz.instanceType)
    }
    else if (member instanceof TypeScript.InterfaceDeclaration) {
    	var name = member.name.text()
        var t = parseInterface(member, qname)
        moduleObject.types.push(name, t)
    }
    else if (member instanceof TypeScript.ImportDeclaration) {
        var ref = parseType(member.alias)
        if (topLevel || TypeScript.hasFlag(member.getVarFlags(), TypeScript.VariableFlags.Exported)) {
            moduleObject.types.push(member.id.text(), ref)
        } else {
        	// private alias to (potentially) publicly visible type
        	current_scope.env.push(member.id.text(), ref) 
        }
    }
    else if (member instanceof TypeScript.ExportAssignment) {
    	// XXX: I think we can actually just ignore these in the tscheck project,
    	// but for completeness, maybe we should export this information somehow
    	// For reference, this is what I *think* happens:
    	// 		declare module "foo" { export = X }
    	// This means import("foo") will return the value in global variable X.
    	// Maybe we need these for modular analysis?
    }
    else {
    	throw new TypeError("Unexpected member in module " + qname + ": " + member.constructor.name)
    }
}
function addModuleMember ( member , moduleObject , qname ) { current_node = member ; var topLevel = qname === '' ; if ( member instanceof TypeScript . FunctionDeclaration ) { var obj = moduleObject . getMember ( member . name . text ( ) ) if ( obj instanceof TObject ) { obj . calls . push ( parseFunctionType ( member ) ) } else { throw new TypeError ( member . name . text ( ) + " is not a function" ) } } else if ( member instanceof TypeScript . VariableStatement ) { member . declaration . declarators . members . forEach ( function ( decl ) { moduleObject . setMember ( decl . id . text ( ) , parseType ( decl . typeExpr ) ) } ) } else if ( member instanceof TypeScript . ModuleDeclaration ) { var name = member . name . text ( ) if ( member . isEnum ( ) ) { // enums are ModuleDeclarations in the AST, but they are semantically quite different var enumObj = moduleObject . getModule ( name ) enumObj . meta . isEnum = true var enumResult = parseEnum ( member , enumObj , qname ) moduleObject . types . push ( name , enumResult . enum ) } else { if ( name [ 0 ] === '"' || name [ 0 ] === "'" ) { // external module? parseExternModule ( member ) } else { var submodule = moduleObject . getModule ( name ) parseModule ( member , submodule , qualify ( qname , name ) ) } } } else if ( member instanceof TypeScript . ClassDeclaration ) { var name = member . name . text ( ) var clazzObj = moduleObject . getModule ( name ) var clazz = parseClass ( member , clazzObj , qname ) // moduleObject.setMember(member.name.text(), clazz.constructorType) moduleObject . types . push ( member . name . text ( ) , clazz . instanceType ) } else if ( member instanceof TypeScript . InterfaceDeclaration ) { var name = member . name . text ( ) var t = parseInterface ( member , qname ) moduleObject . types . push ( name , t ) } else if ( member instanceof TypeScript . ImportDeclaration ) { var ref = parseType ( member . alias ) if ( topLevel || TypeScript . hasFlag ( member . getVarFlags ( ) , TypeScript . VariableFlags . Exported ) ) { moduleObject . types . push ( member . id . text ( ) , ref ) } else { // private alias to (potentially) publicly visible type current_scope . env . push ( member . id . text ( ) , ref ) } } else if ( member instanceof TypeScript . ExportAssignment ) { // XXX: I think we can actually just ignore these in the tscheck project, // but for completeness, maybe we should export this information somehow // For reference, this is what I *think* happens: // 		declare module "foo" { export = X } // This means import("foo") will return the value in global variable X. // Maybe we need these for modular analysis? } else { throw new TypeError ( "Unexpected member in module " + qname + ": " + member . constructor . name ) } }
Some names are resolved before merging, others after. Type parameters must be resolved before merging, because merging generic interfaces requires alpha-renaming of type parameters. Names defined in modules must be resolved after merging, because the whole module type is not available until then.
Some names are resolved before merging others after . Type parameters must be resolved before merging because merging generic interfaces requires alpha - renaming of type parameters . Names defined in modules must be resolved after merging because the whole module type is not available until then .