Skip to content

Commit 58217d3

Browse files
authored
Add isMutableHashMap and isMutableHashSet (#1767)
1 parent 5d704ee commit 58217d3

21 files changed

+80
-15
lines changed

.changeset/odd-boats-think.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
Add `isMutableHashMap` and `isMutableHashSet`, and align nominal guard implementations and tests across collections and transactional data types.

packages/effect/src/Effect.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export declare namespace Yieldable {
372372
* @since 2.0.0
373373
* @category Guards
374374
*/
375-
export const isEffect = (u: unknown): u is Effect<any, any, any> => typeof u === "object" && u !== null && TypeId in u
375+
export const isEffect: (u: unknown) => u is Effect<any, any, any> = core.isEffect
376376

377377
/**
378378
* Iterator interface for Effect generators, enabling Effect values to work with generator functions.
@@ -13270,7 +13270,7 @@ export const annotateLogs = dual<
1327013270
): Effect<A, E, R>
1327113271
}
1327213272
>(
13273-
(args) => core.isEffect(args[0]),
13273+
(args) => isEffect(args[0]),
1327413274
<A, E, R>(
1327513275
effect: Effect<A, E, R>,
1327613276
...args: [Record<string, unknown>] | [key: string, value: unknown]

packages/effect/src/FileSystem.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { pipe } from "./Function.ts"
4343
import * as Layer from "./Layer.ts"
4444
import * as Option from "./Option.ts"
4545
import { badArgument, type PlatformError, systemError } from "./PlatformError.ts"
46+
import { hasProperty } from "./Predicate.ts"
4647
import type * as Pull from "./Pull.ts"
4748
import type { Scope } from "./Scope.ts"
4849
import * as ServiceMap from "./ServiceMap.ts"
@@ -999,7 +1000,7 @@ export const FileTypeId = "~effect/platform/FileSystem/File"
9991000
* @since 4.0.0
10001001
* @category File
10011002
*/
1002-
export const isFile = (u: unknown): u is File => typeof u === "object" && u !== null && FileTypeId in u
1003+
export const isFile = (u: unknown): u is File => hasProperty(u, FileTypeId)
10031004

10041005
/**
10051006
* Interface representing an open file handle.

packages/effect/src/Graph.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { NodeInspectSymbol } from "./Inspectable.ts"
1111
import * as Option from "./Option.ts"
1212
import type { Pipeable } from "./Pipeable.ts"
1313
import { pipeArguments } from "./Pipeable.ts"
14+
import { hasProperty } from "./Predicate.ts"
1415
import type { Mutable } from "./Types.ts"
1516

1617
const TypeId = "~effect/collections/Graph"
@@ -222,7 +223,7 @@ const missingNode = (node: number) => new GraphError({ message: `Node ${node} do
222223
* @since 4.0.0
223224
* @category Guards
224225
*/
225-
export const isGraph = (u: unknown): u is Graph<unknown, unknown> => typeof u === "object" && u !== null && TypeId in u
226+
export const isGraph = (u: unknown): u is Graph<unknown, unknown> => hasProperty(u, TypeId)
226227

227228
/**
228229
* Creates a directed graph, optionally with initial mutations.

packages/effect/src/MutableHashMap.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { type Inspectable, NodeInspectSymbol, toJson } from "./Inspectable.ts"
3333
import * as Option from "./Option.ts"
3434
import type { Pipeable } from "./Pipeable.ts"
3535
import { pipeArguments } from "./Pipeable.ts"
36+
import { hasProperty } from "./Predicate.ts"
3637

3738
const TypeId = "~effect/collections/MutableHashMap"
3839

@@ -71,6 +72,14 @@ export interface MutableHashMap<out K, out V> extends Iterable<[K, V]>, Pipeable
7172
readonly buckets: Map<number, NonEmptyArray<K>>
7273
}
7374

75+
/**
76+
* Checks if the specified value is a `MutableHashMap`, `false` otherwise.
77+
*
78+
* @category refinements
79+
* @since 4.0.0
80+
*/
81+
export const isMutableHashMap = <K, V>(value: unknown): value is MutableHashMap<K, V> => hasProperty(value, TypeId)
82+
7483
const MutableHashMapProto: Omit<MutableHashMap<unknown, unknown>, "backing" | "buckets" | "bucketsSize"> = {
7584
[TypeId]: TypeId,
7685
[Symbol.iterator](this: MutableHashMap<unknown, unknown>): Iterator<[unknown, unknown]> {

packages/effect/src/MutableHashSet.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { type Inspectable, NodeInspectSymbol, toJson } from "./Inspectable.ts"
3030
import * as MutableHashMap from "./MutableHashMap.ts"
3131
import type { Pipeable } from "./Pipeable.ts"
3232
import { pipeArguments } from "./Pipeable.ts"
33+
import { hasProperty } from "./Predicate.ts"
3334

3435
const TypeId = "~effect/collections/MutableHashSet"
3536

@@ -68,6 +69,14 @@ export interface MutableHashSet<out V> extends Iterable<V>, Pipeable, Inspectabl
6869
readonly keyMap: MutableHashMap.MutableHashMap<V, boolean>
6970
}
7071

72+
/**
73+
* Checks if the specified value is a `MutableHashSet`, `false` otherwise.
74+
*
75+
* @category refinements
76+
* @since 4.0.0
77+
*/
78+
export const isMutableHashSet = <V>(value: unknown): value is MutableHashSet<V> => hasProperty(value, TypeId)
79+
7180
const MutableHashSetProto: Omit<MutableHashSet<unknown>, "keyMap"> = {
7281
[TypeId]: TypeId,
7382
[Symbol.iterator](this: MutableHashSet<unknown>): Iterator<unknown> {

packages/effect/src/Resource.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as Exit from "./Exit.ts"
66
import { identity } from "./Function.ts"
77
import { PipeInspectableProto } from "./internal/core.ts"
88
import type { Pipeable } from "./Pipeable.ts"
9+
import { hasProperty } from "./Predicate.ts"
910
import type * as Schedule from "./Schedule.ts"
1011
import type * as Scope from "./Scope.ts"
1112
import * as ScopedRef from "./ScopedRef.ts"
@@ -32,7 +33,7 @@ export interface Resource<in out A, in out E = never> extends Pipeable {
3233
*/
3334
export const isResource: (u: unknown) => u is Resource<unknown, unknown> = (
3435
u: unknown
35-
): u is Resource<unknown, unknown> => typeof u === "object" && u !== null && TypeId in u
36+
): u is Resource<unknown, unknown> => hasProperty(u, TypeId)
3637

3738
const Proto = {
3839
...PipeInspectableProto,

packages/effect/src/SubscriptionRef.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { dual, identity } from "./Function.ts"
66
import { PipeInspectableProto } from "./internal/core.ts"
77
import * as Option from "./Option.ts"
88
import type { Pipeable } from "./Pipeable.ts"
9+
import { hasProperty } from "./Predicate.ts"
910
import * as PubSub from "./PubSub.ts"
1011
import * as Semaphore from "./Semaphore.ts"
1112
import * as Stream from "./Stream.ts"
@@ -29,7 +30,7 @@ export interface SubscriptionRef<in out A> extends SubscriptionRef.Variance<A>,
2930
*/
3031
export const isSubscriptionRef: (u: unknown) => u is SubscriptionRef<unknown> = (
3132
u: unknown
32-
): u is SubscriptionRef<unknown> => typeof u === "object" && u != null && TypeId in u
33+
): u is SubscriptionRef<unknown> => hasProperty(u, TypeId)
3334

3435
/**
3536
* The `SynchronizedRef` namespace containing type definitions and utilities.

packages/effect/src/TxDeferred.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { Option } from "./Option.ts"
1313
import * as O from "./Option.ts"
1414
import type { Pipeable } from "./Pipeable.ts"
1515
import { pipeArguments } from "./Pipeable.ts"
16+
import { hasProperty } from "./Predicate.ts"
1617
import type { Result } from "./Result.ts"
1718
import * as Res from "./Result.ts"
1819
import * as TxRef from "./TxRef.ts"
@@ -270,5 +271,4 @@ export const fail: {
270271
* @since 4.0.0
271272
* @category guards
272273
*/
273-
export const isTxDeferred = (u: unknown): u is TxDeferred<unknown, unknown> =>
274-
typeof u === "object" && u !== null && TypeId in u
274+
export const isTxDeferred = (u: unknown): u is TxDeferred<unknown, unknown> => hasProperty(u, TypeId)

packages/effect/src/TxHashMap.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { NodeInspectSymbol, toJson } from "./Inspectable.ts"
1111
import * as Option from "./Option.ts"
1212
import type { Pipeable } from "./Pipeable.ts"
1313
import { pipeArguments } from "./Pipeable.ts"
14+
import { hasProperty } from "./Predicate.ts"
1415
import type { Result } from "./Result.ts"
1516
import * as TxRef from "./TxRef.ts"
1617

@@ -1158,7 +1159,7 @@ export const setMany: {
11581159
* @category guards
11591160
*/
11601161
export const isTxHashMap = <K, V>(value: unknown): value is TxHashMap<K, V> => {
1161-
return typeof value === "object" && value !== null && TypeId in value
1162+
return hasProperty(value, TypeId)
11621163
}
11631164

11641165
/**

0 commit comments

Comments
 (0)