From 0b6d08e0adc719bc7dd13f0d413d683aa37b45ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Sj=C3=B6green?= Date: Thu, 3 Apr 2025 20:35:29 +0200 Subject: [PATCH 1/2] feat: Prettier `anyOf` unions by using `toSafeUnionString` more sparingly --- deno.json | 2 +- mod.ts | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/deno.json b/deno.json index 1b9b446..ef33f06 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@denosaurs/typefetch", - "version": "0.0.31", + "version": "0.0.32", "exports": { ".": "./main.ts" }, diff --git a/mod.ts b/mod.ts index 24ab635..b3f48c7 100644 --- a/mod.ts +++ b/mod.ts @@ -45,6 +45,12 @@ export function escapeObjectKey(key: string): string { /** * Prevents narrowing of string literal union to string. + * + * @example + * ```ts + * type ThisWillBeNarrowedToString = string | "string" | "number" | "boolean"; + * type ThisWillNotBeNarrowed = NonNullable | "string" | "number" | "boolean"; + * ``` */ function toSafeUnionString( type: string | undefined, @@ -53,6 +59,7 @@ function toSafeUnionString( if (type === "string" && types.length > 1) { return "NonNullable"; } + return type; } @@ -138,9 +145,24 @@ export function toSchemaType( console.groupEnd(); } + // The string union is safe if all types are boolean, string, number, integer, + // object, array or null. Any other value is not known to be safe and we therefore + // use the `toSafeUnionString` function to prevent narrowing of the type. + const safeStringUnion = schema.anyOf.every((schema) => + "type" in schema && + (schema.type === "boolean" || schema.type === "string" || + schema.type === "number" || schema.type === "integer" || + schema.type === "object" || schema.type === "array" || + schema.type === "null") + ); + return schema.anyOf .map((schema) => toSchemaType(document, schema, coerceToString)) - .map((type, _, types) => toSafeUnionString(type, types)) + .map((type, _, types) => + safeStringUnion ? type : toSafeUnionString(type, types) + ) + // Naively removes duplicates. + .filter((type, index, types) => types.indexOf(type) === index) .filter(Boolean) .join("|"); } From 4f7c00d042d74419fc081435401bfca388a4cf1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20Sj=C3=B6green?= Date: Thu, 3 Apr 2025 20:48:21 +0200 Subject: [PATCH 2/2] fix: Stricter check --- mod.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mod.ts b/mod.ts index b3f48c7..1d606f3 100644 --- a/mod.ts +++ b/mod.ts @@ -150,6 +150,8 @@ export function toSchemaType( // use the `toSafeUnionString` function to prevent narrowing of the type. const safeStringUnion = schema.anyOf.every((schema) => "type" in schema && + !("enum" in schema || "oneOf" in schema || + "anyOf" in schema || "allOf" in schema) && (schema.type === "boolean" || schema.type === "string" || schema.type === "number" || schema.type === "integer" || schema.type === "object" || schema.type === "array" ||