From 38480d8ed57b1edb25501564dce971803256b697 Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 14 Aug 2024 13:12:24 +0900 Subject: [PATCH 1/2] test(isObjectOf): add test for value with T object assigned --- is/object_of_test.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/is/object_of_test.ts b/is/object_of_test.ts index 514ef4b..00e301c 100644 --- a/is/object_of_test.ts +++ b/is/object_of_test.ts @@ -33,12 +33,30 @@ Deno.test("isObjectOf", async (t) => { true, "Undefined properties are ignored", ); + }); + + await t.step("returns true on value with T object assigned", () => { + const v = { a: 0, b: "a", c: true }; + // Only 'null' and 'undefined' are not Object.assign-able + assertEquals( + isObjectOf(predObj)(Object.assign("string", v)), + true, + "string", + ); + assertEquals(isObjectOf(predObj)(Object.assign(100, v)), true, "number"); + assertEquals(isObjectOf(predObj)(Object.assign(100n, v)), true, "bigint"); + assertEquals(isObjectOf(predObj)(Object.assign(true, v)), true, "boolean"); + assertEquals(isObjectOf(predObj)(Object.assign([], v)), true, "array"); + assertEquals(isObjectOf(predObj)(Object.assign({}, v)), true, "object"); + assertEquals( + isObjectOf(predObj)(Object.assign(() => {}, v)), + true, + "function", + ); assertEquals( - isObjectOf(predObj)( - Object.assign(() => void 0, { a: 0, b: "a", c: true }), - ), + isObjectOf(predObj)(Object.assign(Symbol("symbol"), v)), true, - "Function are treated as an object", + "symbol", ); }); From 4cf04b4f9190265f37cc9d4bcb71525cf09670ad Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 14 Aug 2024 13:22:35 +0900 Subject: [PATCH 2/2] feat!(isObjectOf): accept any `object` with `Object.assign` See #126 --- is/object_of.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/is/object_of.ts b/is/object_of.ts index 7be8ca9..786f32b 100644 --- a/is/object_of.ts +++ b/is/object_of.ts @@ -9,7 +9,7 @@ import { import type { Predicate } from "../type.ts"; /** - * Return a type predicate function that returns `true` if the type of `x` is `ObjectOf`. + * Return a type predicate function that returns `true` if the type of `x` is/has `ObjectOf`. * * Use {@linkcode isRecordOf} if you want to check if the type of `x` is a record of `T`. * @@ -34,6 +34,12 @@ import type { Predicate } from "../type.ts"; * if (isMyType(a)) { * const _: { a: number; b: string; c?: boolean | undefined, readonly d: string } = a; * } + * + * // It also works for value with Object.assign + * const b: unknown = Object.assign(100, { a: 0, b: "a", d: "d" }); + * if (isMyType(b)) { + * const _: { a: number; b: string; c?: boolean | undefined, readonly d: string } = b; + * } * ``` */ export function isObjectOf< @@ -45,7 +51,7 @@ export function isObjectOf< ].map((k) => [k, predObj[k]]); const pred = rewriteName( (x): x is ObjectOf => { - if (!isObject(x)) return false; + if (x == null) return false; return preds.every(([k, pred]) => pred(x[k])); }, "isObjectOf", @@ -54,13 +60,6 @@ export function isObjectOf< return annotate(pred, "predObj", predObj); } -function isObject(x: unknown): x is Record { - if (x == null) return false; - if (typeof x !== "object" && typeof x !== "function") return false; - if (Array.isArray(x)) return false; - return true; -} - type ObjectOf>> = FlatType< // Readonly/Optional & {