From 27e4fc5b2755c53da6c7152b6be96a2708e06ab4 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 18 Jan 2024 12:46:46 +0100 Subject: [PATCH] fix(utils): Fix `isPlainObject()` check for classes --- packages/utils/src/is.ts | 11 ++++++++++- packages/utils/test/is.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/utils/src/is.ts b/packages/utils/src/is.ts index 12225b9c8b60..d90ebcb405e4 100644 --- a/packages/utils/src/is.ts +++ b/packages/utils/src/is.ts @@ -113,7 +113,16 @@ export function isPrimitive(wat: unknown): wat is Primitive { * @returns A boolean representing the result. */ export function isPlainObject(wat: unknown): wat is Record { - return isBuiltin(wat, 'Object'); + if (!isBuiltin(wat, 'Object')) { + return false; + } + + try { + const name = (Object.getPrototypeOf(wat) as { constructor: { name: string } }).constructor.name; + return !name || name === 'Object'; + } catch { + return true; + } } /** diff --git a/packages/utils/test/is.test.ts b/packages/utils/test/is.test.ts index da9d77a44fde..02378d005c25 100644 --- a/packages/utils/test/is.test.ts +++ b/packages/utils/test/is.test.ts @@ -5,6 +5,7 @@ import { isErrorEvent, isInstanceOf, isNaN, + isPlainObject, isPrimitive, isThenable, isVueViewModel, @@ -144,3 +145,27 @@ describe('isVueViewModel()', () => { expect(isVueViewModel({ foo: true })).toEqual(false); }); }); + +describe('isPlainObject', () => { + class MyClass { + public foo: string = 'bar'; + } + + it.each([ + [{}, true], + [true, false], + [false, false], + [undefined, false], + [null, false], + ['', false], + [1, false], + [0, false], + [{ aha: 'yes' }, true], + [new Object({ aha: 'yes' }), true], + [new String('aa'), false], + [new MyClass(), false], + [{ ...new MyClass() }, true], + ])('%s is %s', (value, expected) => { + expect(isPlainObject(value)).toBe(expected); + }); +});