From 9c1e2b3b8bab2fe4524ba53056aa58e0c9873b21 Mon Sep 17 00:00:00 2001 From: Mangel Maxime Date: Thu, 25 Jun 2026 22:17:15 +0200 Subject: [PATCH] fix(ts): keep enclosing type parameters in scope for nested members --- src/Fable.Transforms/Fable2Babel.fs | 3 +++ tests/Js/Main/TypeTests.fs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Fable.Transforms/Fable2Babel.fs b/src/Fable.Transforms/Fable2Babel.fs index a546e7b2b..08f484b9d 100644 --- a/src/Fable.Transforms/Fable2Babel.fs +++ b/src/Fable.Transforms/Fable2Babel.fs @@ -1406,6 +1406,9 @@ module Util = List.append entGenParams info.GenericParameters |> List.map (fun g -> g.Name) |> set + // Keep type parameters already in scope (e.g. from an enclosing generic + // function) so nested members/lambdas don't redeclare and shadow them. + |> Set.union ctx.ScopedTypeParams let declaredTypeParams = if isAttached then diff --git a/tests/Js/Main/TypeTests.fs b/tests/Js/Main/TypeTests.fs index c39f7bbb2..0347b92f1 100644 --- a/tests/Js/Main/TypeTests.fs +++ b/tests/Js/Main/TypeTests.fs @@ -679,6 +679,16 @@ type GenericMethodEncodableClass() = interface IGenericMethodEncodable with member _.Encode<'json>(helpers: IGenericMethodHelpers<'json>) = helpers.encodeString "x" +type IGenericMethodBox<'T> = + abstract Get: unit -> 'T + +// The lambda inside `Get` references the outer generic parameter 'item (via the +// captured `value`); it must not redeclare and shadow it. +let mapGenericMethodBox<'item> (value: 'item) : IGenericMethodBox<'item seq> = + { new IGenericMethodBox<'item seq> with + member _.Get() : 'item seq = Seq.map (fun (x: 'item) -> value) [ value ] + } + type ConcreteClass1() = inherit MangledAbstractClass5(2) @@ -1760,4 +1770,8 @@ let tests = let encodable = GenericMethodEncodableClass() :> IGenericMethodEncodable encodable.Encode(helpers) |> equal "S:x" + + testCase "Nested lambda does not shadow an outer generic type parameter" <| fun () -> + let box = mapGenericMethodBox 42 + box.Get() |> List.ofSeq |> equal [ 42 ] ]