Repository: TypeScript
Issue: Cannot create declaration files from static factory class returned from a function.
Labels: Bug

**TypeScript Version:**  
2.8 and 2.9

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:** 
Cannot create declaration files from static factory class returned from a function.

**Code**
(pay special attention to `class SomeClass`)
```ts
namespace Test {
    export interface IType<TInstance = object> {
        new(...args: any[]): TInstance;
    }
	
    export function ClassFactory<TBaseClass extends IType, TClass extends any, TFactory extends any, TNamespace extends object>
        (namespace: TNamespace, base: { $__type: TBaseClass }, getType: (base: TBaseClass) => [TClass, TFactory], exportName?: keyof TNamespace, addMemberTypeInfo = true)
        : TClass & TFactory & { $__type: TClass } {
        return null;
    }

    export function FactoryBase<TBaseFactory extends IType>(baseFactoryType: TBaseFactory) {
        return class FactoryBase {
            static 'new'?(...args: any[]): any;
            static init?(o: object, isnew: boolean, ...args: any[]): void;
        };
    }

    function TestDec<T>(c:T):T { return null; }

    export namespace Loader {
        export var _SomeClass = ClassFactory(Loader, void 0,
            (base) => {
                @TestDec
                class SomeClass {
                     static readonly SomeClassFactory = class Factory extends FactoryBase(null) {
                        static 'new'(): SomeClass { return null; }
                        static init(o: SomeClass, isnew: boolean) {
                        }
                    };
                }
                return [SomeClass, SomeClass["SomeClassFactory"]];
            }
        );
    }
}
```

The code compiles and runs OK, no problems.  The issue is that when I enable the flag to export declarations as well I get this error: 

> Scripts/testscript.ts(20,20): error TS4025: Exported variable '_SomeClass' has or is using private name 'SomeClass'.

**Expected behavior:**

It is expected that the `d.ts` files are generated without giving me issues.  Without declarations it compiles fine. The partial workaround (see below) makes the error pointless.

**Actual behavior:**

Error message (see above).

**Other Details:**
This works:
```ts
namespace Test {
    export interface IType<TInstance = object> {
        new(...args: any[]): TInstance;
    }
	
    export function ClassFactory<TBaseClass extends IType, TClass extends any, TFactory extends any, TNamespace extends object>
        (namespace: TNamespace, base: { $__type: TBaseClass }, getType: (base: TBaseClass) => [TClass, TFactory], exportName?: keyof TNamespace, addMemberTypeInfo = true)
        : TClass & TFactory & { $__type: TClass } {
        return null;
    }

    export function FactoryBase<TBaseFactory extends IType>(baseFactoryType: TBaseFactory) {
        return class FactoryBase {
            static 'new'?(...args: any[]): any;
            static init?(o: object, isnew: boolean, ...args: any[]): void;
        };
    }

	function TestDec<T>(c:T):T { return null; }
	
    export namespace Loader {
        export var _SomeClass = ClassFactory(Loader, void 0,
            (base) => {
                // @TestDec <- CANNOT ADD DECORATORS, CANNOT SUPPORT ANGULAR, ETC., WITHOUT UGLY WORKAROUNDS
                var c = class SomeClass {
                     static readonly SomeClassFactory = class Factory extends FactoryBase(null) {
                        static 'new'(): SomeClass { return null; }
                        static init(o: SomeClass, isnew: boolean) {
                        }
                    };
                };
                return [c, c["SomeClassFactory"]];
            }
        );

    }
}
```
Notice however that I lost the `@TestDec` decorator doing this above (YES, I know a decorator is just a function). Not a very pleasant experience for Angular users.

Now, the following code I change `SomeClassFactory` to `protected` and it works ONLY if declarations are turned off; HOWEVER, when declarations are turned are on, this also fails with error: `testscript.ts(22,20): error TS4094: Property 'SomeClassFactory' of exported class expression may not be private or protected.` It's protected for a reason - I do not want people to see it in the code completion list on the exported property.
```
namespace Test {
    export interface IType<TInstance = object> {
        new(...args: any[]): TInstance;
    }
	
    export function ClassFactory<TBaseClass extends IType, TClass extends any, TFactory extends any, TNamespace extends object>
        (namespace: TNamespace, base: { $__type: TBaseClass }, getType: (base: TBaseClass) => [TClass, TFactory], exportName?: keyof TNamespace, addMemberTypeInfo = true)
        : TClass & TFactory & { $__type: TClass } {
        return null;
    }

    export function FactoryBase<TBaseFactory extends IType>(baseFactoryType: TBaseFactory) {
        return class FactoryBase {
            static 'new'?(...args: any[]): any;
            static init?(o: object, isnew: boolean, ...args: any[]): void;
        };
    }

	function TestDec<T>(c:T):T { return null; }
	
    export namespace Loader {
        export var _SomeClass = ClassFactory(Loader, void 0,
            (base) => {
				// @TestDec <- CANNOT ADD DECORATORS, CANNOT SUPPORT ANGULAR, ETC., WITHOUT UGLY WORKAROUNDS
                var c = class SomeClass {
                     protected static readonly SomeClassFactory = class Factory extends FactoryBase(null) {
                        static 'new'(): SomeClass { return null; }
                        static init(o: SomeClass, isnew: boolean) {
                        }
                    };
                };
                return [c, c["SomeClassFactory"]];
            }
        );

    }
}
```
It's very frustrating to have it compile and run PERFECTLY, but then fail to generate declaration files.  I keep getting blocked at every turn and it's driving me nuts lol. It's days like this I just want to switch back to pure JavaScript and save time (except then I realize all the bugs I'll probably get which would offset any time saved coding it lol ... :*( ).