diff --git a/src/compiler.ts b/src/compiler.ts
index 074da6fd..f01c6549 100644
--- a/src/compiler.ts
+++ b/src/compiler.ts
@@ -551,13 +551,15 @@ export class Compiler extends DiagnosticEmitter {
 
       // skip prototype and export instances
       case ElementKind.FUNCTION_PROTOTYPE: {
-        for (let instance of (<FunctionPrototype>element).instances.values()) {
-          let instanceName = name;
-          if (instance.is(CommonFlags.GENERIC)) {
-            let fullName = instance.internalName;
-            instanceName += fullName.substring(fullName.lastIndexOf("<"));
+        for (let instances of (<FunctionPrototype>element).instances.values()) {
+          for (let instance of instances.values()) {
+            let instanceName = name;
+            if (instance.is(CommonFlags.GENERIC)) {
+              let fullName = instance.internalName;
+              instanceName += fullName.substring(fullName.lastIndexOf("<"));
+            }
+            this.makeModuleExport(instanceName, instance, prefix);
           }
-          this.makeModuleExport(instanceName, instance, prefix);
         }
         break;
       }
diff --git a/src/definitions.ts b/src/definitions.ts
index 593fc058..1d054b89 100644
--- a/src/definitions.ts
+++ b/src/definitions.ts
@@ -105,8 +105,10 @@ abstract class ExportsWalker {
   }
 
   private visitFunctionInstances(element: FunctionPrototype): void {
-    for (let instance of element.instances.values()) {
-      if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance);
+    for (let instances of element.instances.values()) {
+      for (let instance of instances.values()) {
+        if (instance.is(CommonFlags.COMPILED)) this.visitFunction(<Function>instance);
+      }
     }
   }
 
@@ -516,8 +518,10 @@ function hasCompiledMember(element: Element): bool {
     for (let member of members.values()) {
       switch (member.kind) {
         case ElementKind.FUNCTION_PROTOTYPE: {
-          for (let instance of (<FunctionPrototype>member).instances.values()) {
-            if (instance.is(CommonFlags.COMPILED)) return true;
+          for (let instances of (<FunctionPrototype>member).instances.values()) {
+            for (let instance of instances.values()) {
+              if (instance.is(CommonFlags.COMPILED)) return true;
+            }
           }
           break;
         }
diff --git a/src/program.ts b/src/program.ts
index 1a6a6a32..73336634 100644
--- a/src/program.ts
+++ b/src/program.ts
@@ -2391,8 +2391,8 @@ export class FunctionPrototype extends Element {
   declaration: FunctionDeclaration;
   /** If an instance method, the class prototype reference. */
   classPrototype: ClassPrototype | null;
-  /** Resolved instances. */
-  instances: Map<string,Function> = new Map();
+  /** Resolved instances by class type arguments and function type arguments. */
+  instances: Map<string,Map<string,Function>> = new Map();
   /** Class type arguments, if a partially resolved method of a generic class. Not set otherwise. */
   classTypeArguments: Type[] | null = null;
   /** Operator kind, if an overload. */
diff --git a/src/resolver.ts b/src/resolver.ts
index 9e20b914..c55059aa 100644
--- a/src/resolver.ts
+++ b/src/resolver.ts
@@ -713,9 +713,14 @@ export class Resolver extends DiagnosticEmitter {
     contextualTypeArguments: Map<string,Type> | null = null,
     reportMode: ReportMode = ReportMode.REPORT
   ): Function | null {
+    var classTypeArguments = prototype.classTypeArguments;
+    var classInstanceKey = classTypeArguments ? typesToString(classTypeArguments) : "";
     var instanceKey = typeArguments ? typesToString(typeArguments) : "";
-    var instance = prototype.instances.get(instanceKey);
-    if (instance) return instance;
+    var classInstances = prototype.instances.get(classInstanceKey);
+    if (classInstances) {
+      let instance = classInstances.get(instanceKey);
+      if (instance) return instance;
+    }
 
     var declaration = prototype.declaration;
     var isInstance = prototype.is(CommonFlags.INSTANCE);
@@ -734,7 +739,6 @@ export class Resolver extends DiagnosticEmitter {
     }
 
     // override with class type arguments if a partially resolved instance method
-    var classTypeArguments = prototype.classTypeArguments;
     if (classTypeArguments) { // set only if partially resolved
       assert(prototype.is(CommonFlags.INSTANCE));
       let classDeclaration = assert(classPrototype).declaration;
@@ -818,7 +822,7 @@ export class Resolver extends DiagnosticEmitter {
 
     var internalName = prototype.internalName;
     if (instanceKey.length) internalName += "<" + instanceKey + ">";
-    instance = new Function(
+    var instance = new Function(
       prototype,
       internalName,
       signature,
@@ -827,7 +831,8 @@ export class Resolver extends DiagnosticEmitter {
         : classPrototype,
       contextualTypeArguments
     );
-    prototype.instances.set(instanceKey, instance);
+    if (!classInstances) prototype.instances.set(classInstanceKey, classInstances = new Map());
+    classInstances.set(instanceKey, instance);
     this.program.instancesLookup.set(internalName, instance);
     return instance;
   }
@@ -856,6 +861,7 @@ export class Resolver extends DiagnosticEmitter {
     partialPrototype.flags = prototype.flags;
     partialPrototype.operatorKind = prototype.operatorKind;
     partialPrototype.classTypeArguments = typeArguments;
+    partialPrototype.instances = prototype.instances;
     return partialPrototype;
   }