diff --git a/src/map.ts b/src/map.ts index c2601ca..f39fc5d 100644 --- a/src/map.ts +++ b/src/map.ts @@ -13,12 +13,12 @@ interface KeyValuePair { /** * A Map implementation that supports deep equality for object keys. */ -export class DeepMap extends Map implements Comparable> { - private readonly normalizer: Normalizer; - private readonly map: Map, KeyValuePair>; +export class DeepMap extends Map implements Comparable> { + private readonly normalizer: Normalizer; + private readonly map: Map, KeyValuePair>; // NOTE: This is actually a thin wrapper. We're not using super other than to drive the (typed) API contract. - constructor(entries?: readonly (readonly [K, V])[] | null, options: Options = {}) { + constructor(entries?: readonly (readonly [K, V])[] | null, options: Options = {}) { super(); this.normalizer = new Normalizer(options); const transformedEntries = entries @@ -142,11 +142,11 @@ export class DeepMap extends Map implements Comparable // PRIVATE METHODS FOLLOW... - private normalizeKey(input: K): Normalized { + private normalizeKey(input: K): Normalized { return this.normalizer.normalizeKey(input); } - private normalizeValue(input: V): Normalized { + private normalizeValue(input: V): Normalized { return this.normalizer.normalizeValue(input); } } diff --git a/src/normalizer.ts b/src/normalizer.ts index bc63f71..c055471 100644 --- a/src/normalizer.ts +++ b/src/normalizer.ts @@ -11,17 +11,17 @@ type HashedObject = string; /** * Type for normalized input. */ -export type Normalized = HashedObject | T | ReturnType>; +export type Normalized = HashedObject | T; /** * Class that normalizes object types to strings via hashing */ -export class Normalizer { +export class Normalizer { private readonly objectHashOptions: ObjectHashOptions; - private readonly keyTransformer: TransformFunction; - private readonly valueTransformer: TransformFunction; + private readonly keyTransformer: TransformFunction; + private readonly valueTransformer: TransformFunction; - constructor(options: Options = {}) { + constructor(options: Options = {}) { const { transformer, mapValueTransformer, useToJsonTransform, ...objectHashOptions } = getOptionsWithDefaults(options); this.keyTransformer = useToJsonTransform ? Transformers.jsonSerializeDeserialize : transformer; @@ -34,7 +34,7 @@ export class Normalizer { * @param input the input to normalize * @returns the normalized result */ - normalizeKey(input: K): Normalized { + normalizeKey(input: K): Normalized { return this.normalizeHelper(this.keyTransformer(input)); } @@ -43,7 +43,7 @@ export class Normalizer { * @param input the input to normalize * @returns the normalized result */ - normalizeValue(input: V): Normalized { + normalizeValue(input: V): Normalized { return this.normalizeHelper(this.valueTransformer(input)); } diff --git a/src/options.ts b/src/options.ts index e1b1359..126b253 100644 --- a/src/options.ts +++ b/src/options.ts @@ -6,20 +6,20 @@ import { Require } from './utils'; /** * Library options */ -interface DeepEqualityDataStructuresOptions { +interface DeepEqualityDataStructuresOptions { /** * A function that transforms Map keys or Set values prior to normalization. * * NOTE: The caller is responsible for not mutating object inputs. */ - transformer?: TransformFunction; + transformer?: TransformFunction; /** * A function that transforms Map values prior to normalization. * * NOTE: The caller is responsible for not mutating object inputs. */ - mapValueTransformer?: TransformFunction; + mapValueTransformer?: TransformFunction; /** * If true, objects will be JSON-serialized/deserialized into "plain" objects prior to hashing. @@ -29,14 +29,14 @@ interface DeepEqualityDataStructuresOptions { useToJsonTransform?: boolean; } -export type Options = ObjectHashOptions & DeepEqualityDataStructuresOptions; +export type Options = ObjectHashOptions & DeepEqualityDataStructuresOptions; /** * Given the specified options, resolve default values as appropriate. */ -export function getOptionsWithDefaults( - options: Options -): Require, keyof DeepEqualityDataStructuresOptions> { +export function getOptionsWithDefaults( + options: Options +): Require, keyof DeepEqualityDataStructuresOptions> { return { // Default options algorithm: 'md5' as const, // not a cryptographic usage, who cares diff --git a/src/set.ts b/src/set.ts index 30147cf..985ad5e 100644 --- a/src/set.ts +++ b/src/set.ts @@ -5,12 +5,12 @@ import { Options } from './options'; /** * A Set implementation that supports deep equality for values. */ -export class DeepSet extends Set implements Comparable> { +export class DeepSet extends Set implements Comparable> { // Just piggy-back on a DeepMap that uses null values - private readonly map: DeepMap; + private readonly map: DeepMap; // NOTE: This is actually a thin wrapper. We're not using super other than to drive the (typed) API contract. - constructor(values?: readonly T[] | null, options?: Options) { + constructor(values?: readonly V[] | null, options?: Options) { super(); const transformedEntries = values ? values.map((el) => [el, null] as const) : null; this.map = new DeepMap(transformedEntries, options); @@ -26,14 +26,14 @@ export class DeepSet extends Set implements Comparable> { /** * Returns true if the given value is present in the set. */ - override has(key: T): boolean { - return this.map.has(key); + override has(val: V): boolean { + return this.map.has(val); } /** * Store the given value. */ - override add(val: T): this { + override add(val: V): this { this.map.set(val, null); return this; } @@ -41,7 +41,7 @@ export class DeepSet extends Set implements Comparable> { /** * Deletes the specified value. */ - override delete(val: T): boolean { + override delete(val: V): boolean { return this.map.delete(val); } @@ -55,7 +55,7 @@ export class DeepSet extends Set implements Comparable> { /** * Standard forEach function. */ - override forEach(callbackfn: (val: T, val2: T, set: Set) => void): void { + override forEach(callbackfn: (val: V, val2: V, set: Set) => void): void { this.map.forEach((_mapVal, mapKey, _map) => { callbackfn(mapKey, mapKey, this); }); @@ -66,7 +66,7 @@ export class DeepSet extends Set implements Comparable> { * * @yields the next value in the set */ - override *[Symbol.iterator](): IterableIterator { + override *[Symbol.iterator](): IterableIterator { for (const [key, _val] of this.map[Symbol.iterator]()) { yield key; } @@ -77,7 +77,7 @@ export class DeepSet extends Set implements Comparable> { * * @yields the next value-value pair in the set */ - override *entries(): IterableIterator<[T, T]> { + override *entries(): IterableIterator<[V, V]> { for (const val of this[Symbol.iterator]()) { yield [val, val]; } @@ -88,7 +88,7 @@ export class DeepSet extends Set implements Comparable> { * * @yields the next key in the map */ - override *keys(): IterableIterator { + override *keys(): IterableIterator { for (const val of this[Symbol.iterator]()) { yield val; } @@ -99,7 +99,7 @@ export class DeepSet extends Set implements Comparable> { * * @yields the next value in the map */ - override *values(): IterableIterator { + override *values(): IterableIterator { yield* this.keys(); } diff --git a/src/transformers.ts b/src/transformers.ts index a949489..9d1a77f 100644 --- a/src/transformers.ts +++ b/src/transformers.ts @@ -1,11 +1,12 @@ -export type TransformFunction = (input: T) => unknown; +export type TransformFunction = (input: T) => R; export class Transformers { - static identity(input: T): T { - return input; + static identity(input: T): R { + // Just make the types happy :) + return input as unknown as R; } - static jsonSerializeDeserialize(obj: T): T { + static jsonSerializeDeserialize(obj: T): R { return JSON.parse(JSON.stringify(obj)); } }