From e1af14e38e7b0956a6557bc4ba61c41cf67cba2e Mon Sep 17 00:00:00 2001 From: Darcy Parker Date: Thu, 4 Nov 2021 12:04:57 -0400 Subject: [PATCH 1/2] Jsonify: handle undefined in array. --- source/jsonify.d.ts | 9 ++++++++- test-d/jsonify.ts | 14 +++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/source/jsonify.d.ts b/source/jsonify.d.ts index bc69492a8..eded0a98d 100644 --- a/source/jsonify.d.ts +++ b/source/jsonify.d.ts @@ -3,6 +3,13 @@ import {JsonPrimitive, JsonValue} from './basic'; // Note: The return value has to be `any` and not `unknown` so it can match `void`. type NotJsonable = ((...args: any[]) => any) | undefined; +// Note: Handles special case where Arrays with `undefined` are transformed to `'null'` by `JSON.stringify()` +// Only use with array members +type JsonifyArrayMember = + T extends undefined ? + null | Exclude : + Jsonify; + /** Transform a type to one that is assignable to the `JsonValue` type. @@ -64,7 +71,7 @@ type Jsonify = ? T extends JsonPrimitive ? T // Primitive is acceptable : T extends Array - ? Array> // It's an array: recursive call for its children + ? Array> // It's an array: recursive call for its children : T extends object ? T extends {toJSON(): infer J} ? (() => J) extends (() => JsonValue) // Is J assignable to JsonValue? diff --git a/test-d/jsonify.ts b/test-d/jsonify.ts index 691fdcd08..bc6889727 100644 --- a/test-d/jsonify.ts +++ b/test-d/jsonify.ts @@ -1,4 +1,4 @@ -import {expectAssignable, expectNotAssignable} from 'tsd'; +import {expectAssignable, expectNotAssignable, expectType} from 'tsd'; import {Jsonify, JsonValue} from '..'; interface A { @@ -122,3 +122,15 @@ class NonJsonWithInvalidToJSON { const nonJsonWithInvalidToJSON = new NonJsonWithInvalidToJSON(); expectNotAssignable(nonJsonWithInvalidToJSON); expectNotAssignable(nonJsonWithInvalidToJSON.toJSON()); + +// Special cases of Array with `undefined` member +// `[undefined]` is not JSON because it contains non JSON value `undefined` +// However `JSON.parse(JSON.stringify())` transforms array members of `undefined` to `null` +expectNotAssignable([undefined]); +declare const parsedStringifiedArrayWithUndefined1: Jsonify<[undefined]>; // = JSON.parse(JSON.stringify([undefined])); +expectType(parsedStringifiedArrayWithUndefined1); +expectAssignable(parsedStringifiedArrayWithUndefined1); +expectNotAssignable([undefined, 1]); +declare const parsedStringifiedArrayWithUndefined2: Jsonify<[undefined, number]>; +expectType>(parsedStringifiedArrayWithUndefined2); +expectAssignable(parsedStringifiedArrayWithUndefined2); From 68474d1fd432c0ee16a94ab0a76bc65da179dba8 Mon Sep 17 00:00:00 2001 From: Darcy Parker <945058+darcyparker@users.noreply.github.com> Date: Tue, 22 Mar 2022 08:04:02 -0400 Subject: [PATCH 2/2] jsonify.ts: Update to test more general Jsonify. --- test-d/jsonify.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-d/jsonify.ts b/test-d/jsonify.ts index 5d0cda481..dd51f51cb 100644 --- a/test-d/jsonify.ts +++ b/test-d/jsonify.ts @@ -127,7 +127,7 @@ expectNotAssignable(nonJsonWithInvalidToJSON.toJSON()); // `[undefined]` is not JSON because it contains non JSON value `undefined` // However `JSON.parse(JSON.stringify())` transforms array members of `undefined` to `null` expectNotAssignable([undefined]); -declare const parsedStringifiedArrayWithUndefined1: Jsonify<[undefined]>; // = JSON.parse(JSON.stringify([undefined])); +declare const parsedStringifiedArrayWithUndefined1: Jsonify; // = JSON.parse(JSON.stringify([undefined])); expectType(parsedStringifiedArrayWithUndefined1); expectAssignable(parsedStringifiedArrayWithUndefined1); expectNotAssignable([undefined, 1]);