diff --git a/src/types.ts b/src/types.ts index de306a6..082bd6d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,6 +47,18 @@ export enum TYPE { NULL = 'NULL', } +const constructorOf = (value: object): unknown => { + return Object.getPrototypeOf(value).constructor +} + +export function isRecord (value: object): boolean { + return constructorOf(value) === Object && Object.keys(Object.getPrototypeOf(value)).length === 0 +} + +export function isRecordLike (value: unknown): boolean { + return typeof value === 'object' && value !== null && (isRecord(value) || Array.isArray(value)) +} + export function typeOf (value: unknown): string { switch (typeof value) { case 'bigint': @@ -76,20 +88,16 @@ export function typeOf (value: unknown): string { return TYPE.ARRAY } - if (value.constructor.name === 'Object') { + if (isRecord(value)) { return TYPE.RECORD } - return 'InstanceOf<' + value.constructor.name + '>' + return 'InstanceOf<' + (constructorOf(value) as { name?: string }).name + '>' } throw new Error() } -export function isRecordLike (value: unknown): boolean { - return typeof value === 'object' && value !== null && ['Array', 'Object'].includes(value.constructor.name) -} - export function isScalar (value: unknown): boolean { switch (typeof value) { case 'bigint': diff --git a/test/unit/types.test.js b/test/unit/types.test.js index d7d5eae..3a8d2c1 100644 --- a/test/unit/types.test.js +++ b/test/unit/types.test.js @@ -15,6 +15,7 @@ describe('types', () => { const records = [ [{}], + [{ constructor: null }], [{ a: 'a', b: ['b'] }], [[]], [['b', 'c']],