Skip to content

Commit 91c8d1c

Browse files
committed
Correct handling of unions of unions
Resolves #2469
1 parent 7b558b0 commit 91c8d1c

File tree

5 files changed

+33
-9
lines changed

5 files changed

+33
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Bug Fixes
44

55
- Fixed an issue where a namespace would not be created for merged function-namespaces only containing types, #2476.
6+
- Fixed an infinite loop when converting a union type which directly contained another union type which refers to itself, #2469.
67

78
## v0.25.6 (2024-01-01)
89

src/lib/converter/types.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,7 @@ export function convertType(
136136
// We need to check it here, not just in the union checker, because typeToTypeNode
137137
// will use the origin when serializing
138138
// aliasSymbol check is important - #2468
139-
if (
140-
typeOrNode.isUnion() &&
141-
typeOrNode.origin &&
142-
!typeOrNode.origin.isUnion() &&
143-
!typeOrNode.aliasSymbol
144-
) {
139+
if (typeOrNode.isUnion() && typeOrNode.origin && !typeOrNode.aliasSymbol) {
145140
return convertType(context, typeOrNode.origin);
146141
}
147142

src/test/TestLogger.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ export class TestLogger extends Logger {
3232
this.messages.splice(index, 1);
3333
}
3434

35+
expectNoMessage(message: string) {
36+
const regex = createRegex(message);
37+
const index = this.messages.findIndex((m) => regex.test(m));
38+
if (index !== -1) {
39+
const messages = this.messages.join("\n\t");
40+
fail(
41+
`Expected "${message}" to not be logged. The logged messages were:\n\t${messages}`,
42+
);
43+
}
44+
}
45+
3546
expectNoOtherMessages({ ignoreDebug } = { ignoreDebug: true }) {
3647
const messages = ignoreDebug
3748
? this.messages.filter((msg) => !msg.startsWith("debug"))

src/test/behavior.c2.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,12 +1086,15 @@ describe("Behavior Tests", () => {
10861086
logger.expectNoOtherMessages();
10871087
});
10881088

1089-
it("Should not produce warnings when processing an object type twice due to intersection", () => {
1089+
it("Should not warn about recursive types", () => {
10901090
const project = convert("refusingToRecurse");
10911091
const schemaTypeBased = query(project, "schemaTypeBased");
10921092
equal(schemaTypeBased.type?.toString(), "Object & Object");
1093+
equal(
1094+
querySig(project, "Map.getFilter").type?.toString(),
1095+
"void | ExpressionSpecification",
1096+
);
10931097

1094-
logger.expectMessage("debug: Begin readme.md*");
1095-
logger.expectNoOtherMessages({ ignoreDebug: false });
1098+
logger.expectNoMessage("debug: Refusing to recurse*");
10961099
});
10971100
});

src/test/converter2/behavior/refusingToRecurse.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ export const schema = {
2727
export type Schema = FromSchema<typeof schema>;
2828

2929
export const schemaTypeBased = null! as Schema;
30+
31+
export type ExpressionSpecification =
32+
| ["array", unknown | ExpressionSpecification]
33+
| [
34+
"array",
35+
string | ExpressionSpecification,
36+
unknown | ExpressionSpecification,
37+
];
38+
39+
export class Map {
40+
getFilter(layerId: string): ExpressionSpecification | void {
41+
return;
42+
}
43+
}

0 commit comments

Comments
 (0)