From 5351533873dbe758cdd528302fbbd2625888d157 Mon Sep 17 00:00:00 2001 From: Donovan Hiland Date: Tue, 26 Sep 2023 12:13:21 -0600 Subject: [PATCH] `Jsonify`: Fix handling of nested objects with only a `name` property (#691) Co-authored-by: Sindre Sorhus --- source/internal.d.ts | 13 ++++++++++--- test-d/jsonify.ts | 11 +++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/internal.d.ts b/source/internal.d.ts index ea479aaa4..863bdad0f 100644 --- a/source/internal.d.ts +++ b/source/internal.d.ts @@ -189,9 +189,16 @@ type BaseKeyFilter = Key extends symbol ? never : Type[Key] extends symbol ? never - : [(...arguments_: any[]) => any] extends [Type[Key]] - ? never - : Key; + /* + To prevent a problem where an object with only a `name` property is incorrectly treated as assignable to a function, we first check if the property is a record. + This check is necessary, because without it, if we don't verify whether the property is a record, an object with a type of `{name: any}` would return `never` due to its potential assignability to a function. + See: https://github.com/sindresorhus/type-fest/issues/657 + */ + : Type[Key] extends Record + ? Key + : [(...arguments_: any[]) => any] extends [Type[Key]] + ? never + : Key; /** Returns the required keys. diff --git a/test-d/jsonify.ts b/test-d/jsonify.ts index 7b3ac0232..b642a2a66 100644 --- a/test-d/jsonify.ts +++ b/test-d/jsonify.ts @@ -327,6 +327,17 @@ expectType<{a: any}>(objectWithAnyProperty); declare const objectWithAnyProperties: Jsonify>; expectType>(objectWithAnyProperties); +// Test for `Jsonify` support for nested objects with _only_ a name property. +// See https://github.com/sindresorhus/type-fest/issues/657 +declare const nestedObjectWithNameProperty: { + first: { + name: string; + }; +}; +declare const jsonifiedNestedObjectWithNameProperty: Jsonify; + +expectType(jsonifiedNestedObjectWithNameProperty); + /// #629 // declare const readonlyTuple: Jsonify; // expectType(readonlyTuple);