diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index cd89bbf688a53..ae4f5fee3b907 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -16738,7 +16738,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
             const type = elementTypes[i];
             const flags = target.elementFlags[i];
             if (flags & ElementFlags.Variadic) {
-                if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
+                if (type.flags & TypeFlags.InstantiableNonPrimitive || everyContainedType(type, isGenericMappedType)) {
                     // Generic variadic elements stay as they are.
                     addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]);
                 }
@@ -30246,13 +30246,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
 
     function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
         return mapType(type, t => {
-            if (isGenericMappedType(t) && !t.declaration.nameType) {
-                const constraint = getConstraintTypeFromMappedType(t);
-                const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
-                const propertyNameType = nameType || getStringLiteralType(unescapeLeadingUnderscores(name));
-                if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
-                    return substituteIndexedMappedType(t, propertyNameType);
-                }
+            if (everyContainedType(t, t => isGenericMappedType(t) && !t.declaration.nameType)) {
+                const newTypes = mapDefined(t.flags & TypeFlags.Intersection ? (t as IntersectionType).types : [t], t => {
+                    const mappedType = t as MappedType;
+                    const constraint = getConstraintTypeFromMappedType(mappedType);
+                    const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
+                    const propertyNameType = nameType || getStringLiteralType(unescapeLeadingUnderscores(name));
+                    if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
+                        return substituteIndexedMappedType(mappedType, propertyNameType);
+                    }
+                });
+                return newTypes.length ? getIntersectionType(newTypes) : undefined;
             }
             else if (t.flags & TypeFlags.StructuredType) {
                 const prop = getPropertyOfType(t, name);
@@ -30486,6 +30490,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
         );
     }
 
+    function getApparentTypeOfInstantiatedContextualType(type: Type) {
+        return getObjectFlags(type) & ObjectFlags.Mapped ? type : getApparentType(type);
+    }
+
     // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
     // be "pushed" onto a node using the contextualType property.
     function getApparentTypeOfContextualType(node: Expression | MethodDeclaration, contextFlags: ContextFlags | undefined): Type | undefined {
@@ -30500,7 +30508,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
                 // That would evaluate mapped types with array or tuple type constraints too eagerly
                 // and thus it would prevent `getTypeOfPropertyOfContextualType` from obtaining per-position contextual type for elements of array literal expressions.
                 // Apparent type of other mapped types is already the mapped type itself so we can just avoid calling `getApparentType` here for all mapped types.
-                t => getObjectFlags(t) & ObjectFlags.Mapped ? t : getApparentType(t),
+                t => {
+                    if (t.flags & TypeFlags.Intersection) {
+                        return getIntersectionType(map((t as IntersectionType).types, getApparentTypeOfInstantiatedContextualType));
+                    }
+                    return getApparentTypeOfInstantiatedContextualType(t);
+                },
                 /*noReductions*/ true,
             );
             return apparentType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as UnionType) :
diff --git a/tests/baselines/reference/reverseMappedIntersectionInference.symbols b/tests/baselines/reference/reverseMappedIntersectionInference.symbols
new file mode 100644
index 0000000000000..855d5a483c66d
--- /dev/null
+++ b/tests/baselines/reference/reverseMappedIntersectionInference.symbols
@@ -0,0 +1,266 @@
+//// [tests/cases/compiler/reverseMappedIntersectionInference.ts] ////
+
+=== reverseMappedIntersectionInference.ts ===
+type Results<T> = {
+>Results : Symbol(Results, Decl(reverseMappedIntersectionInference.ts, 0, 0))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 0, 13))
+
+  [K in keyof T]: {
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 1, 3))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 0, 13))
+
+    data: T[K];
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 1, 19))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 0, 13))
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 1, 3))
+
+    onSuccess: (data: T[K]) => void;
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 2, 15))
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 3, 16))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 0, 13))
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 1, 3))
+
+  };
+};
+
+type Errors<E> = {
+>Errors : Symbol(Errors, Decl(reverseMappedIntersectionInference.ts, 5, 2))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 7, 12))
+
+  [K in keyof E]: {
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 8, 3))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 7, 12))
+
+    error: E[K];
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 8, 19))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 7, 12))
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 8, 3))
+
+    onError: (data: E[K]) => void;
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 9, 16))
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 10, 14))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 7, 12))
+>K : Symbol(K, Decl(reverseMappedIntersectionInference.ts, 8, 3))
+
+  };
+};
+
+declare function withKeyedObj<T, E>(
+>withKeyedObj : Symbol(withKeyedObj, Decl(reverseMappedIntersectionInference.ts, 12, 2))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 14, 30))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 14, 32))
+
+  arg: Results<T> & Errors<E>
+>arg : Symbol(arg, Decl(reverseMappedIntersectionInference.ts, 14, 36))
+>Results : Symbol(Results, Decl(reverseMappedIntersectionInference.ts, 0, 0))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 14, 30))
+>Errors : Symbol(Errors, Decl(reverseMappedIntersectionInference.ts, 5, 2))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 14, 32))
+
+): [T, E];
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 14, 30))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 14, 32))
+
+const res = withKeyedObj({
+>res : Symbol(res, Decl(reverseMappedIntersectionInference.ts, 18, 5))
+>withKeyedObj : Symbol(withKeyedObj, Decl(reverseMappedIntersectionInference.ts, 12, 2))
+
+  a: {
+>a : Symbol(a, Decl(reverseMappedIntersectionInference.ts, 18, 26))
+
+    data: "foo",
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 19, 6))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 20, 16))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 21, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 21, 16))
+
+    },
+    error: 404,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 23, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 24, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 25, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 25, 14))
+
+    },
+  },
+  b: {
+>b : Symbol(b, Decl(reverseMappedIntersectionInference.ts, 28, 4))
+
+    data: true,
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 29, 6))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 30, 15))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 31, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 31, 16))
+
+    },
+    error: 500,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 33, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 34, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 35, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 35, 14))
+
+    },
+  },
+});
+
+declare function withTuples<T extends any[], E extends any[]>(
+>withTuples : Symbol(withTuples, Decl(reverseMappedIntersectionInference.ts, 39, 3))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 41, 28))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 41, 44))
+
+  arg: [...(Results<T> & Errors<E>)]
+>arg : Symbol(arg, Decl(reverseMappedIntersectionInference.ts, 41, 62))
+>Results : Symbol(Results, Decl(reverseMappedIntersectionInference.ts, 0, 0))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 41, 28))
+>Errors : Symbol(Errors, Decl(reverseMappedIntersectionInference.ts, 5, 2))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 41, 44))
+
+): [T, E];
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 41, 28))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 41, 44))
+
+const res2 = withTuples([
+>res2 : Symbol(res2, Decl(reverseMappedIntersectionInference.ts, 45, 5))
+>withTuples : Symbol(withTuples, Decl(reverseMappedIntersectionInference.ts, 39, 3))
+  {
+    data: "foo",
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 46, 3))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 47, 16))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 48, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 48, 16))
+
+    },
+    error: 404,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 50, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 51, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 52, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 52, 14))
+
+    },
+  },
+  {
+    data: true,
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 56, 3))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 57, 15))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 58, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 58, 16))
+
+    },
+    error: 500,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 60, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 61, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 62, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 62, 14))
+
+    },
+  },
+]);
+
+type Tuple<T> = readonly [T, ...T[]];
+>Tuple : Symbol(Tuple, Decl(reverseMappedIntersectionInference.ts, 66, 3))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 68, 11))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 68, 11))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 68, 11))
+
+declare function withTuplesConstraints<T extends Tuple<any>, E extends Tuple<any>>(
+>withTuplesConstraints : Symbol(withTuplesConstraints, Decl(reverseMappedIntersectionInference.ts, 68, 37))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 70, 39))
+>Tuple : Symbol(Tuple, Decl(reverseMappedIntersectionInference.ts, 66, 3))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 70, 60))
+>Tuple : Symbol(Tuple, Decl(reverseMappedIntersectionInference.ts, 66, 3))
+
+  arg: Results<T> & Errors<E>
+>arg : Symbol(arg, Decl(reverseMappedIntersectionInference.ts, 70, 83))
+>Results : Symbol(Results, Decl(reverseMappedIntersectionInference.ts, 0, 0))
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 70, 39))
+>Errors : Symbol(Errors, Decl(reverseMappedIntersectionInference.ts, 5, 2))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 70, 60))
+
+): [T, E];
+>T : Symbol(T, Decl(reverseMappedIntersectionInference.ts, 70, 39))
+>E : Symbol(E, Decl(reverseMappedIntersectionInference.ts, 70, 60))
+
+const res3 = withTuplesConstraints([
+>res3 : Symbol(res3, Decl(reverseMappedIntersectionInference.ts, 74, 5))
+>withTuplesConstraints : Symbol(withTuplesConstraints, Decl(reverseMappedIntersectionInference.ts, 68, 37))
+  {
+    data: "foo",
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 75, 3))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 76, 16))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 77, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 77, 16))
+
+    },
+    error: 404,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 79, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 80, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 81, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 81, 14))
+
+    },
+  },
+  {
+    data: true,
+>data : Symbol(data, Decl(reverseMappedIntersectionInference.ts, 85, 3))
+
+    onSuccess: (dataArg) => {
+>onSuccess : Symbol(onSuccess, Decl(reverseMappedIntersectionInference.ts, 86, 15))
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 87, 16))
+
+      dataArg;
+>dataArg : Symbol(dataArg, Decl(reverseMappedIntersectionInference.ts, 87, 16))
+
+    },
+    error: 500,
+>error : Symbol(error, Decl(reverseMappedIntersectionInference.ts, 89, 6))
+
+    onError: (errorArg) => {
+>onError : Symbol(onError, Decl(reverseMappedIntersectionInference.ts, 90, 15))
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 91, 14))
+
+      errorArg;
+>errorArg : Symbol(errorArg, Decl(reverseMappedIntersectionInference.ts, 91, 14))
+
+    },
+  },
+]);
diff --git a/tests/baselines/reference/reverseMappedIntersectionInference.types b/tests/baselines/reference/reverseMappedIntersectionInference.types
new file mode 100644
index 0000000000000..b1a08efc5f4b4
--- /dev/null
+++ b/tests/baselines/reference/reverseMappedIntersectionInference.types
@@ -0,0 +1,261 @@
+//// [tests/cases/compiler/reverseMappedIntersectionInference.ts] ////
+
+=== reverseMappedIntersectionInference.ts ===
+type Results<T> = {
+>Results : Results<T>
+
+  [K in keyof T]: {
+    data: T[K];
+>data : T[K]
+
+    onSuccess: (data: T[K]) => void;
+>onSuccess : (data: T[K]) => void
+>data : T[K]
+
+  };
+};
+
+type Errors<E> = {
+>Errors : Errors<E>
+
+  [K in keyof E]: {
+    error: E[K];
+>error : E[K]
+
+    onError: (data: E[K]) => void;
+>onError : (data: E[K]) => void
+>data : E[K]
+
+  };
+};
+
+declare function withKeyedObj<T, E>(
+>withKeyedObj : <T, E>(arg: Results<T> & Errors<E>) => [T, E]
+
+  arg: Results<T> & Errors<E>
+>arg : Results<T> & Errors<E>
+
+): [T, E];
+
+const res = withKeyedObj({
+>res : [{ a: string; b: boolean; }, { a: number; b: number; }]
+>withKeyedObj({  a: {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  b: {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },}) : [{ a: string; b: boolean; }, { a: number; b: number; }]
+>withKeyedObj : <T, E>(arg: Results<T> & Errors<E>) => [T, E]
+>{  a: {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  b: {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },} : { a: { data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }; b: { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }; }
+
+  a: {
+>a : { data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }
+>{    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  } : { data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: "foo",
+>data : string
+>"foo" : "foo"
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: string) => void
+>(dataArg) => {      dataArg;    } : (dataArg: string) => void
+>dataArg : string
+
+      dataArg;
+>dataArg : string
+
+    },
+    error: 404,
+>error : number
+>404 : 404
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+  b: {
+>b : { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }
+>{    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  } : { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: true,
+>data : true
+>true : true
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: boolean) => void
+>(dataArg) => {      dataArg;    } : (dataArg: boolean) => void
+>dataArg : boolean
+
+      dataArg;
+>dataArg : boolean
+
+    },
+    error: 500,
+>error : number
+>500 : 500
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+});
+
+declare function withTuples<T extends any[], E extends any[]>(
+>withTuples : <T extends any[], E extends any[]>(arg: [...(Results<T> & Errors<E>)]) => [T, E]
+
+  arg: [...(Results<T> & Errors<E>)]
+>arg : [...Results<T> & Errors<E>]
+
+): [T, E];
+
+const res2 = withTuples([
+>res2 : [[string, boolean], [number, number]]
+>withTuples([  {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },]) : [[string, boolean], [number, number]]
+>withTuples : <T extends any[], E extends any[]>(arg: [...Results<T> & Errors<E>]) => [T, E]
+>[  {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },] : ({ data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; } | { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; })[]
+  {
+>{    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  } : { data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: "foo",
+>data : string
+>"foo" : "foo"
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: string) => void
+>(dataArg) => {      dataArg;    } : (dataArg: string) => void
+>dataArg : string
+
+      dataArg;
+>dataArg : string
+
+    },
+    error: 404,
+>error : number
+>404 : 404
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+  {
+>{    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  } : { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: true,
+>data : true
+>true : true
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: boolean) => void
+>(dataArg) => {      dataArg;    } : (dataArg: boolean) => void
+>dataArg : boolean
+
+      dataArg;
+>dataArg : boolean
+
+    },
+    error: 500,
+>error : number
+>500 : 500
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+]);
+
+type Tuple<T> = readonly [T, ...T[]];
+>Tuple : Tuple<T>
+
+declare function withTuplesConstraints<T extends Tuple<any>, E extends Tuple<any>>(
+>withTuplesConstraints : <T extends Tuple<any>, E extends Tuple<any>>(arg: Results<T> & Errors<E>) => [T, E]
+
+  arg: Results<T> & Errors<E>
+>arg : Results<T> & Errors<E>
+
+): [T, E];
+
+const res3 = withTuplesConstraints([
+>res3 : [[string, boolean], [number, number]]
+>withTuplesConstraints([  {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },]) : [[string, boolean], [number, number]]
+>withTuplesConstraints : <T extends Tuple<any>, E extends Tuple<any>>(arg: Results<T> & Errors<E>) => [T, E]
+>[  {    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  },  {    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  },] : [{ data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }, { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }]
+  {
+>{    data: "foo",    onSuccess: (dataArg) => {      dataArg;    },    error: 404,    onError: (errorArg) => {      errorArg;    },  } : { data: string; onSuccess: (dataArg: string) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: "foo",
+>data : string
+>"foo" : "foo"
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: string) => void
+>(dataArg) => {      dataArg;    } : (dataArg: string) => void
+>dataArg : string
+
+      dataArg;
+>dataArg : string
+
+    },
+    error: 404,
+>error : number
+>404 : 404
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+  {
+>{    data: true,    onSuccess: (dataArg) => {      dataArg;    },    error: 500,    onError: (errorArg) => {      errorArg;    },  } : { data: true; onSuccess: (dataArg: boolean) => void; error: number; onError: (errorArg: number) => void; }
+
+    data: true,
+>data : true
+>true : true
+
+    onSuccess: (dataArg) => {
+>onSuccess : (dataArg: boolean) => void
+>(dataArg) => {      dataArg;    } : (dataArg: boolean) => void
+>dataArg : boolean
+
+      dataArg;
+>dataArg : boolean
+
+    },
+    error: 500,
+>error : number
+>500 : 500
+
+    onError: (errorArg) => {
+>onError : (errorArg: number) => void
+>(errorArg) => {      errorArg;    } : (errorArg: number) => void
+>errorArg : number
+
+      errorArg;
+>errorArg : number
+
+    },
+  },
+]);
diff --git a/tests/cases/compiler/reverseMappedIntersectionInference.ts b/tests/cases/compiler/reverseMappedIntersectionInference.ts
new file mode 100644
index 0000000000000..6d02e9c5fb612
--- /dev/null
+++ b/tests/cases/compiler/reverseMappedIntersectionInference.ts
@@ -0,0 +1,99 @@
+// @strict: true
+// @noEmit: true
+
+type Results<T> = {
+  [K in keyof T]: {
+    data: T[K];
+    onSuccess: (data: T[K]) => void;
+  };
+};
+
+type Errors<E> = {
+  [K in keyof E]: {
+    error: E[K];
+    onError: (data: E[K]) => void;
+  };
+};
+
+declare function withKeyedObj<T, E>(
+  arg: Results<T> & Errors<E>
+): [T, E];
+
+const res = withKeyedObj({
+  a: {
+    data: "foo",
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 404,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+  b: {
+    data: true,
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 500,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+});
+
+declare function withTuples<T extends any[], E extends any[]>(
+  arg: [...(Results<T> & Errors<E>)]
+): [T, E];
+
+const res2 = withTuples([
+  {
+    data: "foo",
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 404,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+  {
+    data: true,
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 500,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+]);
+
+type Tuple<T> = readonly [T, ...T[]];
+
+declare function withTuplesConstraints<T extends Tuple<any>, E extends Tuple<any>>(
+  arg: Results<T> & Errors<E>
+): [T, E];
+
+const res3 = withTuplesConstraints([
+  {
+    data: "foo",
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 404,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+  {
+    data: true,
+    onSuccess: (dataArg) => {
+      dataArg;
+    },
+    error: 500,
+    onError: (errorArg) => {
+      errorArg;
+    },
+  },
+]);
\ No newline at end of file