@@ -46,14 +46,19 @@ let private transformNewUnion com ctx r fsType (unionCase: FSharpUnionCase) (arg
4646 match getUnionPattern fsType unionCase with
4747 | ErasedUnionCase ->
4848 makeTuple r false argExprs
49- | ErasedUnion( tdef, _ genArgs, rule) ->
50- match argExprs with
51- | [] -> transformStringEnum rule unionCase
52- | [ argExpr] -> argExpr
53- | _ when tdef.UnionCases.Count > 1 ->
54- " Erased unions with multiple cases must have one single field: " + ( getFsTypeFullName fsType)
55- |> addErrorAndReturnNull com ctx.InlinePath r
56- | argExprs -> makeTuple r false argExprs
49+ // TODO: Wrap erased unions in type cast so type info is not lost
50+ | ErasedUnion( tdef, _ genArgs, rule, tag) ->
51+ if tag then
52+ ( transformStringEnum rule unionCase):: argExprs |> makeTuple r false
53+ else
54+ match argExprs with
55+ | [] -> transformStringEnum rule unionCase
56+ | [ argExpr] -> argExpr
57+ | _ when tdef.UnionCases.Count > 1 ->
58+ $" Erased unions with multiple fields must have one single case: {getFsTypeFullName fsType}. " +
59+ " To allow multiple cases pass tag argument, e.g.: [<Erase(tag=true)>]"
60+ |> addErrorAndReturnNull com ctx.InlinePath r
61+ | argExprs -> makeTuple r false argExprs
5762 | TypeScriptTaggedUnion _ ->
5863 match argExprs with
5964 | [ argExpr] -> argExpr
@@ -326,10 +331,14 @@ let private transformUnionCaseTest (com: IFableCompiler) (ctx: Context) r
326331 | ErasedUnionCase ->
327332 return " Cannot test erased union cases"
328333 |> addErrorAndReturnNull com ctx.InlinePath r
329- | ErasedUnion( tdef, genArgs, rule) ->
330- match unionCase.Fields.Count with
331- | 0 -> return makeEqOp r unionExpr ( transformStringEnum rule unionCase) BinaryEqual
332- | 1 ->
334+ | ErasedUnion( tdef, genArgs, rule, tag) ->
335+ match tag, unionCase.Fields.Count with
336+ | true , _ ->
337+ let tagName = transformStringEnum rule unionCase
338+ let tagExpr = Fable.Get( unionExpr, Fable.TupleIndex 0 , Fable.String, None)
339+ return makeEqOp r tagExpr tagName BinaryEqual
340+ | false , 0 -> return makeEqOp r unionExpr ( transformStringEnum rule unionCase) BinaryEqual
341+ | false , 1 ->
333342 let fi = unionCase.Fields[ 0 ]
334343 let typ =
335344 if fi.FieldType.IsGenericParameter then
@@ -341,7 +350,7 @@ let private transformUnionCaseTest (com: IFableCompiler) (ctx: Context) r
341350 else fi.FieldType
342351 let kind = makeType ctx.GenericArgs typ |> Fable.TypeTest
343352 return Fable.Test( unionExpr, kind, r)
344- | _ ->
353+ | false , _ ->
345354 return " Erased unions with multiple cases cannot have more than one field: " + ( getFsTypeFullName fsType)
346355 |> addErrorAndReturnNull com ctx.InlinePath r
347356 | TypeScriptTaggedUnion (_, _, tagName, rule) ->
@@ -863,16 +872,16 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
863872 return Fable.Get( tupleExpr, Fable.TupleIndex tupleElemIndex, typ, makeRangeFrom fsExpr)
864873
865874 | FSharpExprPatterns.UnionCaseGet ( IgnoreAddressOf unionExpr, fsType, unionCase, field) ->
875+ let getIndex () = unionCase.Fields |> Seq.findIndex ( fun x -> x.Name = field.Name)
866876 let r = makeRangeFrom fsExpr
867877 let! unionExpr = transformExpr com ctx unionExpr
868878 match getUnionPattern fsType unionCase with
869879 | ErasedUnionCase ->
870- let index = unionCase.Fields |> Seq.findIndex ( fun x -> x.Name = field.Name)
871- return Fable.Get( unionExpr, Fable.TupleIndex( index), makeType ctx.GenericArgs fsType, r)
872- | ErasedUnion _ ->
873- if unionCase.Fields.Count = 1 then return unionExpr
880+ return Fable.Get( unionExpr, Fable.TupleIndex( getIndex()), makeType ctx.GenericArgs fsType, r)
881+ | ErasedUnion(_ tdef, _ genArgs, _ rule, tag) ->
882+ if not tag && unionCase.Fields.Count = 1 then return unionExpr
874883 else
875- let index = unionCase.Fields |> Seq.findIndex ( fun x -> x.Name = field.Name )
884+ let index = if tag then getIndex () + 1 else getIndex ( )
876885 return Fable.Get( unionExpr, Fable.TupleIndex index, makeType ctx.GenericArgs fsType, r)
877886 | TypeScriptTaggedUnion _ ->
878887 if unionCase.Fields.Count = 1 then return unionExpr
0 commit comments