From d743202a0ae413118b1c163a72ff51818a3ec822 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 16 Jul 2023 11:52:31 +0200 Subject: [PATCH] Revert "Revert "`Jsonify`: Fix handling of tuples (#638)"" This reverts commit 9fdac37ea5e1ea7fcc444a8df95c8eafe88dca2f. --- source/jsonify.d.ts | 20 +++++++++++++++----- test-d/jsonify.ts | 3 +++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/source/jsonify.d.ts b/source/jsonify.d.ts index a9039058a..1894ee250 100644 --- a/source/jsonify.d.ts +++ b/source/jsonify.d.ts @@ -1,16 +1,26 @@ import type {JsonPrimitive, JsonValue} from './basic'; import type {EmptyObject} from './empty-object'; import type {UndefinedToOptional} from './internal'; +import type {IsAny} from './is-any'; +import type {IsNever} from './is-never'; import type {NegativeInfinity, PositiveInfinity} from './numeric'; import type {TypedArray} from './typed-array'; -import type {IsAny} from './is-any'; // Note: The return value has to be `any` and not `unknown` so it can match `void`. type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol; -type JsonifyTuple = { - [Key in keyof T]: T[Key] extends NotJsonable ? null : Jsonify; -}; +type FilterNonNever = T extends [infer F, ...infer R] + ? IsNever extends true + ? FilterNonNever + : [F, ...FilterNonNever] + : IsNever extends true + ? [] + : T; + +// Handles tuples and arrays +type JsonifyList = T extends [infer F, ...infer R] + ? FilterNonNever<[Jsonify, ...JsonifyList]> + : Array>; type FilterJsonableKeys = { [Key in keyof T]: T[Key] extends NotJsonable ? never : Key; @@ -107,7 +117,7 @@ export type Jsonify = IsAny extends true : T extends [] ? [] : T extends [unknown, ...unknown[]] - ? JsonifyTuple + ? JsonifyList : T extends ReadonlyArray ? Array> : T extends object diff --git a/test-d/jsonify.ts b/test-d/jsonify.ts index e2e88ee3c..7b3ac0232 100644 --- a/test-d/jsonify.ts +++ b/test-d/jsonify.ts @@ -222,6 +222,9 @@ expectType<[string, string]>(tupleJson); declare const tupleRestJson: Jsonify<[string, ...Date[]]>; expectType<[string, ...string[]]>(tupleRestJson); +declare const tupleStringJson: Jsonify; +expectType<['some value']>(tupleStringJson); + // BigInt fails JSON.stringify declare const bigInt: Jsonify; expectType(bigInt);