diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 590cebef919fb..05203d714d3ba 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -22679,11 +22679,12 @@ namespace ts {
             return false;
         }
 
-        function getAccessedPropertyName(access: AccessExpression | BindingElement): __String | undefined {
+        function getAccessedPropertyName(access: AccessExpression | BindingElement | ParameterDeclaration): __String | undefined {
             let propertyName;
             return access.kind === SyntaxKind.PropertyAccessExpression ? access.name.escapedText :
                 access.kind === SyntaxKind.ElementAccessExpression && isStringOrNumericLiteralLike(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) :
                 access.kind === SyntaxKind.BindingElement && (propertyName = getDestructuringPropertyName(access)) ? escapeLeadingUnderscores(propertyName) :
+                access.kind === SyntaxKind.Parameter ? ("" + access.parent.parameters.indexOf(access)) as __String :
                 undefined;
         }
 
@@ -24105,13 +24106,14 @@ namespace ts {
             }
 
             function getCandidateDiscriminantPropertyAccess(expr: Expression) {
-                if (isBindingPattern(reference)) {
-                    // When the reference is a binding pattern, we are narrowing a pesudo-reference in getNarrowedTypeOfSymbol.
-                    // An identifier for a destructuring variable declared in the same binding pattern is a candidate.
+                if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference)) {
+                    // When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in
+                    // getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or
+                    // parameter declared in the same parameter list is a candidate.
                     if (isIdentifier(expr)) {
                         const symbol = getResolvedSymbol(expr);
                         const declaration = symbol.valueDeclaration;
-                        if (declaration && isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && reference === declaration.parent) {
+                        if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) {
                             return declaration;
                         }
                     }
@@ -24158,7 +24160,7 @@ namespace ts {
                 return undefined;
             }
 
-            function narrowTypeByDiscriminant(type: Type, access: AccessExpression | BindingElement, narrowType: (t: Type) => Type): Type {
+            function narrowTypeByDiscriminant(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, narrowType: (t: Type) => Type): Type {
                 const propName = getAccessedPropertyName(access);
                 if (propName === undefined) {
                     return type;
@@ -24176,7 +24178,7 @@ namespace ts {
                 });
             }
 
-            function narrowTypeByDiscriminantProperty(type: Type, access: AccessExpression | BindingElement, operator: SyntaxKind, value: Expression, assumeTrue: boolean) {
+            function narrowTypeByDiscriminantProperty(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, operator: SyntaxKind, value: Expression, assumeTrue: boolean) {
                 if ((operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) && type.flags & TypeFlags.Union) {
                     const keyPropertyName = getKeyPropertyName(type as UnionType);
                     if (keyPropertyName && keyPropertyName === getAccessedPropertyName(access)) {
@@ -24191,7 +24193,7 @@ namespace ts {
                 return narrowTypeByDiscriminant(type, access, t => narrowTypeByEquality(t, operator, value, assumeTrue));
             }
 
-            function narrowTypeBySwitchOnDiscriminantProperty(type: Type, access: AccessExpression | BindingElement, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) {
+            function narrowTypeBySwitchOnDiscriminantProperty(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) {
                 if (clauseStart < clauseEnd && type.flags & TypeFlags.Union && getKeyPropertyName(type as UnionType) === getAccessedPropertyName(access)) {
                     const clauseTypes = getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd);
                     const candidate = getUnionType(map(clauseTypes, t => getConstituentTypeForKeyType(type as UnionType, t) || unknownType));
@@ -24969,42 +24971,78 @@ namespace ts {
         }
 
         function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier) {
-            // If we have a non-rest binding element with no initializer declared as a const variable or a const-like
-            // parameter (a parameter for which there are no assignments in the function body), and if the parent type
-            // for the destructuring is a union type, one or more of the binding elements may represent discriminant
-            // properties, and we want the effects of conditional checks on such discriminants to affect the types of
-            // other binding elements from the same destructuring. Consider:
-            //
-            //   type Action =
-            //       | { kind: 'A', payload: number }
-            //       | { kind: 'B', payload: string };
-            //
-            //   function f1({ kind, payload }: Action) {
-            //       if (kind === 'A') {
-            //           payload.toFixed();
-            //       }
-            //       if (kind === 'B') {
-            //           payload.toUpperCase();
-            //       }
-            //   }
-            //
-            // Above, we want the conditional checks on 'kind' to affect the type of 'payload'. To facilitate this, we use
-            // the binding pattern AST instance for '{ kind, payload }' as a pseudo-reference and narrow this reference
-            // as if it occurred in the specified location. We then recompute the narrowed binding element type by
-            // destructuring from the narrowed parent type.
             const declaration = symbol.valueDeclaration;
-            if (declaration && isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && declaration.parent.elements.length >= 2) {
-                const parent = declaration.parent.parent;
-                if (parent.kind === SyntaxKind.VariableDeclaration && getCombinedNodeFlags(declaration) & NodeFlags.Const || parent.kind === SyntaxKind.Parameter) {
-                    const links = getNodeLinks(location);
-                    if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) {
-                        links.flags |= NodeCheckFlags.InCheckIdentifier;
-                        const parentType = getTypeForBindingElementParent(parent);
-                        links.flags &= ~NodeCheckFlags.InCheckIdentifier;
-                        if (parentType && parentType.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) {
-                            const pattern = declaration.parent;
-                            const narrowedType = getFlowTypeOfReference(pattern, parentType, parentType, /*flowContainer*/ undefined, location.flowNode);
-                            return getBindingElementTypeFromParentType(declaration, narrowedType);
+            if (declaration) {
+                // If we have a non-rest binding element with no initializer declared as a const variable or a const-like
+                // parameter (a parameter for which there are no assignments in the function body), and if the parent type
+                // for the destructuring is a union type, one or more of the binding elements may represent discriminant
+                // properties, and we want the effects of conditional checks on such discriminants to affect the types of
+                // other binding elements from the same destructuring. Consider:
+                //
+                //   type Action =
+                //       | { kind: 'A', payload: number }
+                //       | { kind: 'B', payload: string };
+                //
+                //   function f({ kind, payload }: Action) {
+                //       if (kind === 'A') {
+                //           payload.toFixed();
+                //       }
+                //       if (kind === 'B') {
+                //           payload.toUpperCase();
+                //       }
+                //   }
+                //
+                // Above, we want the conditional checks on 'kind' to affect the type of 'payload'. To facilitate this, we use
+                // the binding pattern AST instance for '{ kind, payload }' as a pseudo-reference and narrow this reference
+                // as if it occurred in the specified location. We then recompute the narrowed binding element type by
+                // destructuring from the narrowed parent type.
+                if (isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && declaration.parent.elements.length >= 2) {
+                    const parent = declaration.parent.parent;
+                    if (parent.kind === SyntaxKind.VariableDeclaration && getCombinedNodeFlags(declaration) & NodeFlags.Const || parent.kind === SyntaxKind.Parameter) {
+                        const links = getNodeLinks(location);
+                        if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) {
+                            links.flags |= NodeCheckFlags.InCheckIdentifier;
+                            const parentType = getTypeForBindingElementParent(parent);
+                            links.flags &= ~NodeCheckFlags.InCheckIdentifier;
+                            if (parentType && parentType.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) {
+                                const pattern = declaration.parent;
+                                const narrowedType = getFlowTypeOfReference(pattern, parentType, parentType, /*flowContainer*/ undefined, location.flowNode);
+                                return getBindingElementTypeFromParentType(declaration, narrowedType);
+                            }
+                        }
+                    }
+                }
+                // If we have a const-like parameter with no type annotation or initializer, and if the parameter is contextually
+                // typed by a signature with a single rest parameter of a union of tuple types, one or more of the parameters may
+                // represent discriminant tuple elements, and we want the effects of conditional checks on such discriminants to
+                // affect the types of other parameters in the same parameter list. Consider:
+                //
+                //   type Action = [kind: 'A', payload: number] | [kind: 'B', payload: string];
+                //
+                //   const f: (...args: Action) => void = (kind, payload) => {
+                //       if (kind === 'A') {
+                //           payload.toFixed();
+                //       }
+                //       if (kind === 'B') {
+                //           payload.toUpperCase();
+                //       }
+                //   }
+                //
+                // Above, we want the conditional checks on 'kind' to affect the type of 'payload'. To facilitate this, we use
+                // the arrow function AST node for '(kind, payload) => ...' as a pseudo-reference and narrow this reference as
+                // if it occurred in the specified location. We then recompute the narrowed parameter type by indexing into the
+                // narrowed tuple type.
+                if (isParameter(declaration) && !declaration.type && !declaration.initializer && !declaration.dotDotDotToken) {
+                    const func = declaration.parent;
+                    if (func.parameters.length >= 2 && isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
+                        const contextualSignature = getContextualSignature(func);
+                        if (contextualSignature && contextualSignature.parameters.length === 1 && signatureHasRestParameter(contextualSignature)) {
+                            const restType = getTypeOfSymbol(contextualSignature.parameters[0]);
+                            if (restType.flags & TypeFlags.Union && everyType(restType, isTupleType) && !isSymbolAssigned(symbol)) {
+                                const narrowedType = getFlowTypeOfReference(func, restType, restType, /*flowContainer*/ undefined, location.flowNode);
+                                const index = func.parameters.indexOf(declaration) - (getThisParameter(func) ? 1 : 0);
+                                return getIndexedAccessType(narrowedType, getNumberLiteralType(index));
+                            }
                         }
                     }
                 }
diff --git a/tests/baselines/reference/dependentDestructuredVariables.js b/tests/baselines/reference/dependentDestructuredVariables.js
index ac99a33df54bd..2eb7be3d946a4 100644
--- a/tests/baselines/reference/dependentDestructuredVariables.js
+++ b/tests/baselines/reference/dependentDestructuredVariables.js
@@ -167,6 +167,64 @@ const { value, done } = it.next();
 if (!done) {
     value;  // number
 }
+
+// Repro from #46658
+
+declare function f50(cb: (...args: Args) => void): void
+
+f50((kind, data) => {
+    if (kind === 'A') {
+        data.toFixed();
+    }
+    if (kind === 'B') {
+        data.toUpperCase();
+    }
+});
+
+const f51: (...args: ['A', number] | ['B', string]) => void = (kind, payload) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    if (kind === 'B') {
+        payload.toUpperCase();
+    }
+};
+
+const f52: (...args: ['A', number] | ['B']) => void = (kind, payload?) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    else {
+        payload;  // undefined
+    }
+};
+
+declare function readFile(path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void): void;
+
+readFile('hello', (err, data) => {
+    if (err === null) {
+        data.length;
+    }
+    else {
+        err.message;
+    }
+});
+
+type ReducerArgs = ["add", { a: number, b: number }] | ["concat", { firstArr: any[], secondArr: any[] }];
+
+const reducer: (...args: ReducerArgs) => void = (op, args) => {
+    switch (op) {
+        case "add":
+            console.log(args.a + args.b);
+            break;
+        case "concat":
+            console.log(args.firstArr.concat(args.secondArr));
+            break;
+    }
+}
+
+reducer("add", { a: 1, b: 3 });
+reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] });
 
 
 //// [dependentDestructuredVariables.js]
@@ -292,6 +350,50 @@ const { value, done } = it.next();
 if (!done) {
     value; // number
 }
+f50((kind, data) => {
+    if (kind === 'A') {
+        data.toFixed();
+    }
+    if (kind === 'B') {
+        data.toUpperCase();
+    }
+});
+const f51 = (kind, payload) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    if (kind === 'B') {
+        payload.toUpperCase();
+    }
+};
+const f52 = (kind, payload) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    else {
+        payload; // undefined
+    }
+};
+readFile('hello', (err, data) => {
+    if (err === null) {
+        data.length;
+    }
+    else {
+        err.message;
+    }
+});
+const reducer = (op, args) => {
+    switch (op) {
+        case "add":
+            console.log(args.a + args.b);
+            break;
+        case "concat":
+            console.log(args.firstArr.concat(args.secondArr));
+            break;
+    }
+};
+reducer("add", { a: 1, b: 3 });
+reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] });
 
 
 //// [dependentDestructuredVariables.d.ts]
@@ -355,3 +457,15 @@ declare type Action3 = {
 declare const reducerBroken: (state: number, { type, payload }: Action3) => number;
 declare var it: Iterator<number>;
 declare const value: any, done: boolean | undefined;
+declare function f50(cb: (...args: Args) => void): void;
+declare const f51: (...args: ['A', number] | ['B', string]) => void;
+declare const f52: (...args: ['A', number] | ['B']) => void;
+declare function readFile(path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void): void;
+declare type ReducerArgs = ["add", {
+    a: number;
+    b: number;
+}] | ["concat", {
+    firstArr: any[];
+    secondArr: any[];
+}];
+declare const reducer: (...args: ReducerArgs) => void;
diff --git a/tests/baselines/reference/dependentDestructuredVariables.symbols b/tests/baselines/reference/dependentDestructuredVariables.symbols
index 7c8d0649bf018..bad7fbf5b690e 100644
--- a/tests/baselines/reference/dependentDestructuredVariables.symbols
+++ b/tests/baselines/reference/dependentDestructuredVariables.symbols
@@ -434,3 +434,164 @@ if (!done) {
 >value : Symbol(value, Decl(dependentDestructuredVariables.ts, 164, 7))
 }
 
+// Repro from #46658
+
+declare function f50(cb: (...args: Args) => void): void
+>f50 : Symbol(f50, Decl(dependentDestructuredVariables.ts, 167, 1))
+>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 171, 21))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 171, 26))
+>Args : Symbol(Args, Decl(dependentDestructuredVariables.ts, 111, 1))
+
+f50((kind, data) => {
+>f50 : Symbol(f50, Decl(dependentDestructuredVariables.ts, 167, 1))
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 173, 5))
+>data : Symbol(data, Decl(dependentDestructuredVariables.ts, 173, 10))
+
+    if (kind === 'A') {
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 173, 5))
+
+        data.toFixed();
+>data.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+>data : Symbol(data, Decl(dependentDestructuredVariables.ts, 173, 10))
+>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+    }
+    if (kind === 'B') {
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 173, 5))
+
+        data.toUpperCase();
+>data.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
+>data : Symbol(data, Decl(dependentDestructuredVariables.ts, 173, 10))
+>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
+    }
+});
+
+const f51: (...args: ['A', number] | ['B', string]) => void = (kind, payload) => {
+>f51 : Symbol(f51, Decl(dependentDestructuredVariables.ts, 182, 5))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 182, 12))
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 182, 63))
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 182, 68))
+
+    if (kind === 'A') {
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 182, 63))
+
+        payload.toFixed();
+>payload.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 182, 68))
+>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+    }
+    if (kind === 'B') {
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 182, 63))
+
+        payload.toUpperCase();
+>payload.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 182, 68))
+>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
+    }
+};
+
+const f52: (...args: ['A', number] | ['B']) => void = (kind, payload?) => {
+>f52 : Symbol(f52, Decl(dependentDestructuredVariables.ts, 191, 5))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 191, 12))
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 191, 55))
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 191, 60))
+
+    if (kind === 'A') {
+>kind : Symbol(kind, Decl(dependentDestructuredVariables.ts, 191, 55))
+
+        payload.toFixed();
+>payload.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 191, 60))
+>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
+    }
+    else {
+        payload;  // undefined
+>payload : Symbol(payload, Decl(dependentDestructuredVariables.ts, 191, 60))
+    }
+};
+
+declare function readFile(path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void): void;
+>readFile : Symbol(readFile, Decl(dependentDestructuredVariables.ts, 198, 2))
+>path : Symbol(path, Decl(dependentDestructuredVariables.ts, 200, 26))
+>callback : Symbol(callback, Decl(dependentDestructuredVariables.ts, 200, 39))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 200, 51))
+>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
+
+readFile('hello', (err, data) => {
+>readFile : Symbol(readFile, Decl(dependentDestructuredVariables.ts, 198, 2))
+>err : Symbol(err, Decl(dependentDestructuredVariables.ts, 202, 19))
+>data : Symbol(data, Decl(dependentDestructuredVariables.ts, 202, 23))
+
+    if (err === null) {
+>err : Symbol(err, Decl(dependentDestructuredVariables.ts, 202, 19))
+
+        data.length;
+>data.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
+>data : Symbol(data, Decl(dependentDestructuredVariables.ts, 202, 23))
+>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
+    }
+    else {
+        err.message;
+>err.message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --))
+>err : Symbol(err, Decl(dependentDestructuredVariables.ts, 202, 19))
+>message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --))
+    }
+});
+
+type ReducerArgs = ["add", { a: number, b: number }] | ["concat", { firstArr: any[], secondArr: any[] }];
+>ReducerArgs : Symbol(ReducerArgs, Decl(dependentDestructuredVariables.ts, 209, 3))
+>a : Symbol(a, Decl(dependentDestructuredVariables.ts, 211, 28))
+>b : Symbol(b, Decl(dependentDestructuredVariables.ts, 211, 39))
+>firstArr : Symbol(firstArr, Decl(dependentDestructuredVariables.ts, 211, 67))
+>secondArr : Symbol(secondArr, Decl(dependentDestructuredVariables.ts, 211, 84))
+
+const reducer: (...args: ReducerArgs) => void = (op, args) => {
+>reducer : Symbol(reducer, Decl(dependentDestructuredVariables.ts, 213, 5))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 16))
+>ReducerArgs : Symbol(ReducerArgs, Decl(dependentDestructuredVariables.ts, 209, 3))
+>op : Symbol(op, Decl(dependentDestructuredVariables.ts, 213, 49))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 52))
+
+    switch (op) {
+>op : Symbol(op, Decl(dependentDestructuredVariables.ts, 213, 49))
+
+        case "add":
+            console.log(args.a + args.b);
+>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
+>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
+>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
+>args.a : Symbol(a, Decl(dependentDestructuredVariables.ts, 211, 28))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 52))
+>a : Symbol(a, Decl(dependentDestructuredVariables.ts, 211, 28))
+>args.b : Symbol(b, Decl(dependentDestructuredVariables.ts, 211, 39))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 52))
+>b : Symbol(b, Decl(dependentDestructuredVariables.ts, 211, 39))
+
+            break;
+        case "concat":
+            console.log(args.firstArr.concat(args.secondArr));
+>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
+>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
+>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
+>args.firstArr.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
+>args.firstArr : Symbol(firstArr, Decl(dependentDestructuredVariables.ts, 211, 67))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 52))
+>firstArr : Symbol(firstArr, Decl(dependentDestructuredVariables.ts, 211, 67))
+>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
+>args.secondArr : Symbol(secondArr, Decl(dependentDestructuredVariables.ts, 211, 84))
+>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 213, 52))
+>secondArr : Symbol(secondArr, Decl(dependentDestructuredVariables.ts, 211, 84))
+
+            break;
+    }
+}
+
+reducer("add", { a: 1, b: 3 });
+>reducer : Symbol(reducer, Decl(dependentDestructuredVariables.ts, 213, 5))
+>a : Symbol(a, Decl(dependentDestructuredVariables.ts, 224, 16))
+>b : Symbol(b, Decl(dependentDestructuredVariables.ts, 224, 22))
+
+reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] });
+>reducer : Symbol(reducer, Decl(dependentDestructuredVariables.ts, 213, 5))
+>firstArr : Symbol(firstArr, Decl(dependentDestructuredVariables.ts, 225, 19))
+>secondArr : Symbol(secondArr, Decl(dependentDestructuredVariables.ts, 225, 37))
+
diff --git a/tests/baselines/reference/dependentDestructuredVariables.types b/tests/baselines/reference/dependentDestructuredVariables.types
index de8851a3661db..a1b16d186ee08 100644
--- a/tests/baselines/reference/dependentDestructuredVariables.types
+++ b/tests/baselines/reference/dependentDestructuredVariables.types
@@ -471,3 +471,209 @@ if (!done) {
 >value : number
 }
 
+// Repro from #46658
+
+declare function f50(cb: (...args: Args) => void): void
+>f50 : (cb: (...args: Args) => void) => void
+>cb : (...args: Args) => void
+>args : Args
+
+f50((kind, data) => {
+>f50((kind, data) => {    if (kind === 'A') {        data.toFixed();    }    if (kind === 'B') {        data.toUpperCase();    }}) : void
+>f50 : (cb: (...args: Args) => void) => void
+>(kind, data) => {    if (kind === 'A') {        data.toFixed();    }    if (kind === 'B') {        data.toUpperCase();    }} : (kind: "A" | "B", data: string | number) => void
+>kind : "A" | "B"
+>data : string | number
+
+    if (kind === 'A') {
+>kind === 'A' : boolean
+>kind : "A" | "B"
+>'A' : "A"
+
+        data.toFixed();
+>data.toFixed() : string
+>data.toFixed : (fractionDigits?: number | undefined) => string
+>data : number
+>toFixed : (fractionDigits?: number | undefined) => string
+    }
+    if (kind === 'B') {
+>kind === 'B' : boolean
+>kind : "A" | "B"
+>'B' : "B"
+
+        data.toUpperCase();
+>data.toUpperCase() : string
+>data.toUpperCase : () => string
+>data : string
+>toUpperCase : () => string
+    }
+});
+
+const f51: (...args: ['A', number] | ['B', string]) => void = (kind, payload) => {
+>f51 : (...args: ['A', number] | ['B', string]) => void
+>args : ["A", number] | ["B", string]
+>(kind, payload) => {    if (kind === 'A') {        payload.toFixed();    }    if (kind === 'B') {        payload.toUpperCase();    }} : (kind: "A" | "B", payload: string | number) => void
+>kind : "A" | "B"
+>payload : string | number
+
+    if (kind === 'A') {
+>kind === 'A' : boolean
+>kind : "A" | "B"
+>'A' : "A"
+
+        payload.toFixed();
+>payload.toFixed() : string
+>payload.toFixed : (fractionDigits?: number | undefined) => string
+>payload : number
+>toFixed : (fractionDigits?: number | undefined) => string
+    }
+    if (kind === 'B') {
+>kind === 'B' : boolean
+>kind : "A" | "B"
+>'B' : "B"
+
+        payload.toUpperCase();
+>payload.toUpperCase() : string
+>payload.toUpperCase : () => string
+>payload : string
+>toUpperCase : () => string
+    }
+};
+
+const f52: (...args: ['A', number] | ['B']) => void = (kind, payload?) => {
+>f52 : (...args: ['A', number] | ['B']) => void
+>args : ["A", number] | ["B"]
+>(kind, payload?) => {    if (kind === 'A') {        payload.toFixed();    }    else {        payload;  // undefined    }} : (kind: "A" | "B", payload?: number | undefined) => void
+>kind : "A" | "B"
+>payload : number | undefined
+
+    if (kind === 'A') {
+>kind === 'A' : boolean
+>kind : "A" | "B"
+>'A' : "A"
+
+        payload.toFixed();
+>payload.toFixed() : string
+>payload.toFixed : (fractionDigits?: number | undefined) => string
+>payload : number
+>toFixed : (fractionDigits?: number | undefined) => string
+    }
+    else {
+        payload;  // undefined
+>payload : undefined
+    }
+};
+
+declare function readFile(path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void): void;
+>readFile : (path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void) => void
+>path : string
+>callback : (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void
+>args : [err: null, data: unknown[]] | [err: Error, data: undefined]
+>null : null
+
+readFile('hello', (err, data) => {
+>readFile('hello', (err, data) => {    if (err === null) {        data.length;    }    else {        err.message;    }}) : void
+>readFile : (path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void) => void
+>'hello' : "hello"
+>(err, data) => {    if (err === null) {        data.length;    }    else {        err.message;    }} : (err: Error | null, data: unknown[] | undefined) => void
+>err : Error | null
+>data : unknown[] | undefined
+
+    if (err === null) {
+>err === null : boolean
+>err : Error | null
+>null : null
+
+        data.length;
+>data.length : number
+>data : unknown[]
+>length : number
+    }
+    else {
+        err.message;
+>err.message : string
+>err : Error
+>message : string
+    }
+});
+
+type ReducerArgs = ["add", { a: number, b: number }] | ["concat", { firstArr: any[], secondArr: any[] }];
+>ReducerArgs : ReducerArgs
+>a : number
+>b : number
+>firstArr : any[]
+>secondArr : any[]
+
+const reducer: (...args: ReducerArgs) => void = (op, args) => {
+>reducer : (...args: ReducerArgs) => void
+>args : ReducerArgs
+>(op, args) => {    switch (op) {        case "add":            console.log(args.a + args.b);            break;        case "concat":            console.log(args.firstArr.concat(args.secondArr));            break;    }} : (op: "add" | "concat", args: { a: number; b: number; } | { firstArr: any[]; secondArr: any[]; }) => void
+>op : "add" | "concat"
+>args : { a: number; b: number; } | { firstArr: any[]; secondArr: any[]; }
+
+    switch (op) {
+>op : "add" | "concat"
+
+        case "add":
+>"add" : "add"
+
+            console.log(args.a + args.b);
+>console.log(args.a + args.b) : void
+>console.log : (...data: any[]) => void
+>console : Console
+>log : (...data: any[]) => void
+>args.a + args.b : number
+>args.a : number
+>args : { a: number; b: number; }
+>a : number
+>args.b : number
+>args : { a: number; b: number; }
+>b : number
+
+            break;
+        case "concat":
+>"concat" : "concat"
+
+            console.log(args.firstArr.concat(args.secondArr));
+>console.log(args.firstArr.concat(args.secondArr)) : void
+>console.log : (...data: any[]) => void
+>console : Console
+>log : (...data: any[]) => void
+>args.firstArr.concat(args.secondArr) : any[]
+>args.firstArr.concat : { (...items: ConcatArray<any>[]): any[]; (...items: any[]): any[]; }
+>args.firstArr : any[]
+>args : { firstArr: any[]; secondArr: any[]; }
+>firstArr : any[]
+>concat : { (...items: ConcatArray<any>[]): any[]; (...items: any[]): any[]; }
+>args.secondArr : any[]
+>args : { firstArr: any[]; secondArr: any[]; }
+>secondArr : any[]
+
+            break;
+    }
+}
+
+reducer("add", { a: 1, b: 3 });
+>reducer("add", { a: 1, b: 3 }) : void
+>reducer : (...args: ReducerArgs) => void
+>"add" : "add"
+>{ a: 1, b: 3 } : { a: number; b: number; }
+>a : number
+>1 : 1
+>b : number
+>3 : 3
+
+reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] });
+>reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }) : void
+>reducer : (...args: ReducerArgs) => void
+>"concat" : "concat"
+>{ firstArr: [1, 2], secondArr: [3, 4] } : { firstArr: number[]; secondArr: number[]; }
+>firstArr : number[]
+>[1, 2] : number[]
+>1 : 1
+>2 : 2
+>secondArr : number[]
+>[3, 4] : number[]
+>3 : 3
+>4 : 4
+
diff --git a/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts b/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts
index c7a3f911acbfc..38bcb68d048e8 100644
--- a/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts
+++ b/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts
@@ -170,3 +170,61 @@ const { value, done } = it.next();
 if (!done) {
     value;  // number
 }
+
+// Repro from #46658
+
+declare function f50(cb: (...args: Args) => void): void
+
+f50((kind, data) => {
+    if (kind === 'A') {
+        data.toFixed();
+    }
+    if (kind === 'B') {
+        data.toUpperCase();
+    }
+});
+
+const f51: (...args: ['A', number] | ['B', string]) => void = (kind, payload) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    if (kind === 'B') {
+        payload.toUpperCase();
+    }
+};
+
+const f52: (...args: ['A', number] | ['B']) => void = (kind, payload?) => {
+    if (kind === 'A') {
+        payload.toFixed();
+    }
+    else {
+        payload;  // undefined
+    }
+};
+
+declare function readFile(path: string, callback: (...args: [err: null, data: unknown[]] | [err: Error, data: undefined]) => void): void;
+
+readFile('hello', (err, data) => {
+    if (err === null) {
+        data.length;
+    }
+    else {
+        err.message;
+    }
+});
+
+type ReducerArgs = ["add", { a: number, b: number }] | ["concat", { firstArr: any[], secondArr: any[] }];
+
+const reducer: (...args: ReducerArgs) => void = (op, args) => {
+    switch (op) {
+        case "add":
+            console.log(args.a + args.b);
+            break;
+        case "concat":
+            console.log(args.firstArr.concat(args.secondArr));
+            break;
+    }
+}
+
+reducer("add", { a: 1, b: 3 });
+reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] });