Skip to content

Commit f5723a2

Browse files
authored
fix(ts): keep enclosing type parameters in scope for nested members (#4691)
1 parent 0d6498d commit f5723a2

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

src/Fable.Transforms/Fable2Babel.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,9 @@ module Util =
14061406
List.append entGenParams info.GenericParameters
14071407
|> List.map (fun g -> g.Name)
14081408
|> set
1409+
// Keep type parameters already in scope (e.g. from an enclosing generic
1410+
// function) so nested members/lambdas don't redeclare and shadow them.
1411+
|> Set.union ctx.ScopedTypeParams
14091412

14101413
let declaredTypeParams =
14111414
if isAttached then

tests/Js/Main/TypeTests.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,16 @@ type GenericMethodEncodableClass() =
679679
interface IGenericMethodEncodable with
680680
member _.Encode<'json>(helpers: IGenericMethodHelpers<'json>) = helpers.encodeString "x"
681681

682+
type IGenericMethodBox<'T> =
683+
abstract Get: unit -> 'T
684+
685+
// The lambda inside `Get` references the outer generic parameter 'item (via the
686+
// captured `value`); it must not redeclare and shadow it.
687+
let mapGenericMethodBox<'item> (value: 'item) : IGenericMethodBox<'item seq> =
688+
{ new IGenericMethodBox<'item seq> with
689+
member _.Get() : 'item seq = Seq.map (fun (x: 'item) -> value) [ value ]
690+
}
691+
682692
type ConcreteClass1() =
683693
inherit MangledAbstractClass5(2)
684694

@@ -1760,4 +1770,8 @@ let tests =
17601770

17611771
let encodable = GenericMethodEncodableClass() :> IGenericMethodEncodable
17621772
encodable.Encode(helpers) |> equal "S:x"
1773+
1774+
testCase "Nested lambda does not shadow an outer generic type parameter" <| fun () ->
1775+
let box = mapGenericMethodBox 42
1776+
box.Get() |> List.ofSeq |> equal [ 42 ]
17631777
]

0 commit comments

Comments
 (0)