Made an interface for all key-value iterables out there

This commit is contained in:
Kir_Antipov 2022-12-30 03:17:55 +00:00
parent e3439aa021
commit af85b577f1
2 changed files with 44 additions and 0 deletions

View file

@ -0,0 +1,24 @@
/**
* Represents an object that contains key-value pairs and exposes an `entries()` method
* to iterate over those pairs.
*/
export interface KeyValueIterable<K, V> {
/**
* Returns an iterable containing the key-value pairs of the object.
*/
entries(): Iterable<[K, V]>;
}
/**
* Type guard to check if the given object implements the {@link KeyValueIterable} interface.
*
* @template K - The key type.
* @template V - The value type.
*
* @param obj - The object to check.
*
* @returns `true` if the object implements the {@link KeyValueIterable} interface; otherwise, `false`.
*/
export function isKeyValueIterable<K, V>(obj: unknown): obj is KeyValueIterable<K, V> {
return typeof (obj as KeyValueIterable<K, V>)?.entries === "function";
}

View file

@ -0,0 +1,20 @@
import { isKeyValueIterable } from "@/utils/collections/key-value-iterable";
describe("isKeyValueIterable", () => {
test("returns true for objects that have entries", () => {
expect(isKeyValueIterable(new Map())).toBe(true);
expect(isKeyValueIterable(new Set())).toBe(true);
expect(isKeyValueIterable([])).toBe(true);
expect(isKeyValueIterable({ entries: () => [] })).toBe(true);
});
test("returns false for objects that has no entries", () => {
expect(isKeyValueIterable({})).toBe(false);
expect(isKeyValueIterable(new Date())).toBe(false);
});
test("returns false for null and undefined", () => {
expect(isKeyValueIterable(null)).toBe(false);
expect(isKeyValueIterable(undefined)).toBe(false);
});
});