Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Commit 57e4539

Browse files
committed
Fix unions with mixed types
1 parent 0bfb025 commit 57e4539

File tree

2 files changed

+61
-7
lines changed

2 files changed

+61
-7
lines changed

generator.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -683,39 +683,47 @@ func hasEnumReference(v cue.Value) bool {
683683
func(v cue.Value) bool { return targetsKind(cue.Dereference(v), TypeEnum) },
684684
)
685685

686-
// Check if it setting an enum value [Enum & "value"]
686+
// Check if it's setting an enum value [Enum & "value"]
687687
op, args := v.Expr()
688688
if op == cue.AndOp {
689689
return hasPred
690690
}
691691

692-
// Check if it has default value [Enum & (*"defaultValuee" | _)]
692+
// Check if it has default value [Enum & (*"defaultValue" | _)]
693693
for _, a := range args {
694694
if a.IncompleteKind() == cue.TopKind {
695695
return hasPred
696696
}
697697
}
698698

699-
// Check if it is a union [(Enum & "a") | (Enum & "b")]
700699
isUnion := true
700+
allEnums := true
701701
for _, a := range args {
702+
// Check if it is a union [(Enum & "a") | (Enum & "b")]
702703
if a.Kind() != a.IncompleteKind() {
703704
isUnion = false
704705
}
706+
// Check if all elements are enums
707+
_, exprs := a.Expr()
708+
for _, e := range exprs {
709+
if t, err := getKindFor(cue.Dereference(e)); err == nil && t != TypeEnum {
710+
allEnums = false
711+
}
712+
}
705713
}
706714

707-
return hasPred && isUnion
715+
return hasPred && isUnion && allEnums
708716
}
709717

710718
func hasTypeReference(v cue.Value) bool {
711719
hasTypeRef := containsCuetsyReference(v, TypeAlias)
712-
// Check if it setting an enum value [Enum & "value"]
720+
// Check if it's setting an enum value [Type & "value"]
713721
op, args := v.Expr()
714722
if op == cue.AndOp || op == cue.SelectorOp {
715723
return hasTypeRef
716724
}
717725

718-
// Check if it has default value [Enum & (*"defaultValuee" | _)]
726+
// Check if it has default value [Type & (*"defaultValue" | _)]
719727
for _, a := range args {
720728
if a.IncompleteKind() == cue.TopKind {
721729
return hasTypeRef
@@ -995,7 +1003,7 @@ func (g generator) tsPrintDefault(v cue.Value) (bool, ts.Expr, error) {
9951003
return false, nil, err
9961004
}
9971005

998-
if isReference(d) {
1006+
if isReference(d) && (hasEnumReference(v) || hasTypeReference(v)) {
9991007
switch t := expr.(type) {
10001008
case tsast.SelectorExpr:
10011009
t.Sel.Name = "default" + t.Sel.Name
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
-- cue --
2+
3+
#Enum: "a" | "b" | "c" @cuetsy(kind="enum",memberNames="First|Second|Third")
4+
#Type: "typeA" | "typeB" @cuetsy(kind="type")
5+
6+
#Struct: {
7+
union: #Enum | #Type
8+
enumValue: { #Enum & "a" } | #Type
9+
typeValue: #Enum | { #Type & "typeA" }
10+
bothValue: { #Enum & "a" } | { #Type & "typeA" }
11+
defaultEnumValue: *{ #Enum & "a" } | #Type
12+
defaultTypeValue: #Enum | *{ #Type & "typeA" }
13+
defaultEnum: *#Enum | #Type
14+
defaultType: #Enum | *#Type
15+
defaultMixed: #Enum | { #Type & "typeA"} | *32 | { #Enum & "b" }
16+
} @cuetsy(kind="interface")
17+
18+
-- ts --
19+
20+
export enum Enum {
21+
First = 'a',
22+
Second = 'b',
23+
Third = 'c',
24+
}
25+
26+
export type Type = ('typeA' | 'typeB');
27+
28+
export interface Struct {
29+
bothValue: (Enum.First | 'typeA');
30+
defaultEnum: (Enum | Type);
31+
defaultEnumValue: (Enum.First | Type);
32+
defaultMixed: (Enum | 'typeA' | 32 | Enum.Second);
33+
defaultType: (Enum | Type);
34+
defaultTypeValue: (Enum | 'typeA');
35+
enumValue: (Enum.First | Type);
36+
typeValue: (Enum | 'typeA');
37+
union: (Enum | Type);
38+
}
39+
40+
export const defaultStruct: Partial<Struct> = {
41+
defaultEnum: Enum,
42+
defaultEnumValue: Enum.First,
43+
defaultMixed: 32,
44+
defaultType: Type,
45+
defaultTypeValue: 'typeA',
46+
};

0 commit comments

Comments
 (0)