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);