Skip to content

Commit 9def062

Browse files
JsonTypeInfo used with interfaces (refs #91)
1 parent 3a012e8 commit 9def062

File tree

5 files changed

+81
-9
lines changed

5 files changed

+81
-9
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/compiler/ModelCompiler.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,11 @@ private TsModel processModel(SymbolTable symbolTable, Model model) {
8686
private Map<Type, List<BeanModel>> createChildrenMap(Model model) {
8787
final Map<Type, List<BeanModel>> children = new LinkedHashMap<>();
8888
for (BeanModel bean : model.getBeans()) {
89-
final Type parent = bean.getParent();
90-
if (parent != null) {
91-
if (!children.containsKey(parent)) {
92-
children.put(parent, new ArrayList<BeanModel>());
89+
for (Type ancestor : bean.getDirectAncestors()) {
90+
if (!children.containsKey(ancestor)) {
91+
children.put(ancestor, new ArrayList<BeanModel>());
9392
}
94-
children.get(parent).add(bean);
93+
children.get(ancestor).add(bean);
9594
}
9695
}
9796
return children;

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/BeanModel.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
package cz.habarta.typescript.generator.parser;
33

44
import java.lang.reflect.Type;
5-
import java.util.List;
5+
import java.util.*;
66

77

88
public class BeanModel extends DeclarationModel {
@@ -44,6 +44,15 @@ public List<Type> getInterfaces() {
4444
return interfaces;
4545
}
4646

47+
public List<Type> getDirectAncestors() {
48+
final List<Type> ancestors = new ArrayList<>();
49+
if (parent != null) {
50+
ancestors.add(parent);
51+
}
52+
ancestors.addAll(interfaces);
53+
return ancestors;
54+
}
55+
4756
public List<PropertyModel> getProperties() {
4857
return properties;
4958
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson2Parser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ protected BeanModel parseBean(SourceType<Class<?>> sourceClass) {
8888
// this is parent
8989
discriminantProperty = getDiscriminantPropertyName(jsonTypeInfo);
9090
discriminantLiteral = null;
91-
} else if (isSupported(parentJsonTypeInfo = getAnnotationRecursive(sourceClass.type, JsonTypeInfo.class))) {
92-
// this is child
91+
} else if (!sourceClass.type.isInterface() && isSupported(parentJsonTypeInfo = getAnnotationRecursive(sourceClass.type, JsonTypeInfo.class))) {
92+
// this is child class
9393
discriminantProperty = getDiscriminantPropertyName(parentJsonTypeInfo);
9494
discriminantLiteral = getTypeName(sourceClass.type);
9595
} else {

typescript-generator-core/src/test/java/cz/habarta/typescript/generator/TaggedUnionsTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,35 @@ private static class Circle extends Shape {
4040
public double radius;
4141
}
4242

43+
44+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "kind")
45+
@JsonSubTypes({
46+
@JsonSubTypes.Type(CSquare2.class),
47+
@JsonSubTypes.Type(CRectangle2.class),
48+
@JsonSubTypes.Type(CCircle2.class),
49+
})
50+
private static interface IShape2 {
51+
}
52+
53+
private static interface IQuadrilateral2 extends IShape2 {
54+
}
55+
56+
@JsonTypeName("square")
57+
private static class CSquare2 implements IQuadrilateral2 {
58+
public double size;
59+
}
60+
61+
@JsonTypeName("rectangle")
62+
private static class CRectangle2 implements IQuadrilateral2 {
63+
public double width;
64+
public double height;
65+
}
66+
67+
@JsonTypeName("circle")
68+
private static class CCircle2 implements IShape2 {
69+
public double radius;
70+
}
71+
4372
@Test
4473
public void testTaggedUnions() {
4574
final Settings settings = TestUtils.settings();
@@ -76,6 +105,41 @@ public void testTaggedUnions() {
76105
Assert.assertEquals(expected, output);
77106
}
78107

108+
@Test
109+
public void testTaggedUnionsWithInterfaces() {
110+
final Settings settings = TestUtils.settings();
111+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(IShape2.class));
112+
final String expected = (
113+
"\n" +
114+
"interface IShape2 {\n" +
115+
" kind: 'circle' | 'square' | 'rectangle';\n" +
116+
"}\n" +
117+
"\n" +
118+
"interface CSquare2 extends IQuadrilateral2 {\n" +
119+
" kind: 'square';\n" +
120+
" size: number;\n" +
121+
"}\n" +
122+
"\n" +
123+
"interface CRectangle2 extends IQuadrilateral2 {\n" +
124+
" kind: 'rectangle';\n" +
125+
" width: number;\n" +
126+
" height: number;\n" +
127+
"}\n" +
128+
"\n" +
129+
"interface CCircle2 extends IShape2 {\n" +
130+
" kind: 'circle';\n" +
131+
" radius: number;\n" +
132+
"}\n" +
133+
"\n" +
134+
"interface IQuadrilateral2 extends IShape2 {\n" +
135+
"}\n" +
136+
"\n" +
137+
"type IShape2Union = CSquare2 | CRectangle2 | CCircle2;\n" +
138+
""
139+
).replace('\'', '"');
140+
Assert.assertEquals(expected, output);
141+
}
142+
79143
@Test
80144
public void testTaggedUnionsDisabled() {
81145
final Settings settings = TestUtils.settings();

typescript-generator-core/src/test/java/cz/habarta/typescript/generator/TypeGuardsForJackson2PolymorphismExtensionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void testInTypeScriptGenerator() {
4040
settings.addTypeNamePrefix = "Json";
4141
settings.extensions.add(new TypeGuardsForJackson2PolymorphismExtension());
4242
final String actual = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Point.class));
43-
Assert.assertTrue(actual.contains("type: string;"));
43+
Assert.assertTrue(actual.contains("type: \"cartesian\" | \"polar\";"));
4444
Assert.assertTrue(actual.contains("function isJsonCartesianPoint(jsonPoint: JsonPoint): jsonPoint is JsonCartesianPoint {"));
4545
}
4646

0 commit comments

Comments
 (0)