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