From ccfc8b4929c98576deb1ed5762c2151da0fdc61c Mon Sep 17 00:00:00 2001 From: Emiya Date: Sat, 26 Aug 2023 21:39:25 +0800 Subject: [PATCH] fix: #629 jsonify array --- source/jsonify.d.ts | 27 ++++++++++++++------------- test-d/jsonify.ts | 7 +++++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/source/jsonify.d.ts b/source/jsonify.d.ts index 1894ee250..b013d806f 100644 --- a/source/jsonify.d.ts +++ b/source/jsonify.d.ts @@ -3,24 +3,25 @@ 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 {IsUnknown} from './is-unknown'; import type {NegativeInfinity, PositiveInfinity} from './numeric'; import type {TypedArray} from './typed-array'; +import type {Writable} from './writable'; +import type {WritableDeep} from './writable-deep'; // Note: The return value has to be `any` and not `unknown` so it can match `void`. type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol; -type FilterNonNever = T extends [infer F, ...infer R] - ? IsNever extends true - ? FilterNonNever - : [F, ...FilterNonNever] - : IsNever extends true - ? [] - : T; +type NeverToNull = IsNever extends true ? null : T; // Handles tuples and arrays -type JsonifyList = T extends [infer F, ...infer R] - ? FilterNonNever<[Jsonify, ...JsonifyList]> - : Array>; +type JsonifyList = T extends [] + ? [] + : T extends [infer F, ...infer R] + ? [NeverToNull>, ...JsonifyList] + : IsUnknown extends true + ? [] + : Array>; type FilterJsonableKeys = { [Key in keyof T]: T[Key] extends NotJsonable ? never : Key; @@ -116,10 +117,10 @@ export type Jsonify = IsAny extends true : Jsonify // Maybe if we look a level deeper we'll find a JsonValue : T extends [] ? [] - : T extends [unknown, ...unknown[]] + : T extends unknown[] ? JsonifyList - : T extends ReadonlyArray - ? Array> + : T extends readonly unknown[] + ? JsonifyList> : T extends object ? JsonifyObject> // JsonifyObject recursive call for its children : never; // Otherwise any other non-object is removed diff --git a/test-d/jsonify.ts b/test-d/jsonify.ts index 7b3ac0232..16fd48a6e 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 mixTupleJson: Jsonify<['1', typeof fn, 2]>; +expectType<['1', null, 2]>(mixTupleJson); + declare const tupleStringJson: Jsonify; expectType<['some value']>(tupleStringJson); @@ -328,5 +331,5 @@ declare const objectWithAnyProperties: Jsonify>; expectType>(objectWithAnyProperties); /// #629 -// declare const readonlyTuple: Jsonify; -// expectType(readonlyTuple); +declare const readonlyTuple: Jsonify; +expectType<[1, 2, 3]>(readonlyTuple);