Skip to content

Commit

Permalink
feat: support autocomplete hack on literals or unions of literals (#1930
Browse files Browse the repository at this point in the history
)
  • Loading branch information
domoritz committed Apr 20, 2024
1 parent 4afd56e commit c7b9199
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
12 changes: 10 additions & 2 deletions src/NodeParser/IntersectionNodeParser.ts
Expand Up @@ -11,6 +11,8 @@ import { UndefinedType } from "../Type/UndefinedType.js";
import { NeverType } from "../Type/NeverType.js";
import { ObjectType } from "../Type/ObjectType.js";
import { StringType } from "../Type/StringType.js";
import { LiteralType } from "../Type/LiteralType.js";
import { isLiteralUnion } from "../TypeFormatter/LiteralUnionTypeFormatter.js";

export class IntersectionNodeParser implements SubNodeParser {
public constructor(
Expand All @@ -31,8 +33,14 @@ export class IntersectionNodeParser implements SubNodeParser {
}

// handle autocomplete hacks like `string & {}`
if (types.length === 2 && types.some((t) => t instanceof StringType) && types.some((t) => isEmptyObject(t))) {
return new StringType(true);
if (types.length === 2 && types.some((t) => isEmptyObject(t))) {
if (types.some((t) => t instanceof StringType)) {
return new StringType(true);
}
const nonObject = types.find((t) => !isEmptyObject(t));
if (nonObject instanceof LiteralType || (nonObject instanceof UnionType && isLiteralUnion(nonObject))) {
return nonObject;
}
}

return translate(types);
Expand Down
2 changes: 1 addition & 1 deletion src/TypeFormatter/LiteralUnionTypeFormatter.ts
Expand Up @@ -83,7 +83,7 @@ function flattenTypes(type: UnionType): (StringType | LiteralType | NullType)[]
});
}

function isLiteralUnion(type: UnionType): boolean {
export function isLiteralUnion(type: UnionType): boolean {
return flattenTypes(type).every(
(item) => item instanceof LiteralType || item instanceof NullType || item instanceof StringType,
);
Expand Down
1 change: 1 addition & 0 deletions test/valid-data/string-literals-hack/main.ts
Expand Up @@ -11,4 +11,5 @@ export type MyObject = {
withHack: "foo" | "bar" | (string & {});
withHackRecord: "foo" | "bar" | (string & Record<never, never>);
withHackNull: "foo" | "bar" | null | (string & Record<never, never>);
hackOnLiteral: ("foo" & Record<never, never>) | "bar";
};
10 changes: 9 additions & 1 deletion test/valid-data/string-literals-hack/schema.json
Expand Up @@ -5,6 +5,13 @@
"MyObject": {
"additionalProperties": false,
"properties": {
"hackOnLiteral": {
"enum": [
"foo",
"bar"
],
"type": "string"
},
"literalWithNull": {
"enum": [
"foo",
Expand Down Expand Up @@ -106,7 +113,8 @@
"withRefWithString",
"withHack",
"withHackRecord",
"withHackNull"
"withHackNull",
"hackOnLiteral"
],
"type": "object"
}
Expand Down

0 comments on commit c7b9199

Please sign in to comment.