Skip to content

Commit

Permalink
add Types.DeepMutable (#2628)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusmarminge authored and tim-smart committed Apr 30, 2024
1 parent 92d56db commit ba64ea6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-shrimps-kneel.md
@@ -0,0 +1,5 @@
---
"effect": minor
---

add `Types.DeepMutable`, an alternative to `Types.Mutable` that makes all properties recursively mutable
24 changes: 24 additions & 0 deletions packages/effect/dtslint/Types.ts
Expand Up @@ -72,6 +72,30 @@ hole<Types.Mutable<readonly [string, number]>>()
// $ExpectType { [x: string]: number; }
hole<Types.Simplify<Types.Mutable<{ readonly [_: string]: number }>>>()

// -------------------------------------------------------------------------------------
// DeepMutable
// -------------------------------------------------------------------------------------

type TaggedValues<A> = {
readonly _tag: string
readonly value: ReadonlyArray<A>
}

// $ExpectType [string, number, boolean, bigint]
hole<[Types.DeepMutable<string>, Types.DeepMutable<number>, Types.DeepMutable<boolean>, Types.DeepMutable<bigint>]>()

// $ExpectType { [x: string]: number; }
hole<Types.DeepMutable<{ readonly [_: string]: number }>>()

// $ExpectType Set<{ value: { _tag: string; value: number[]; }; }>
hole<Types.DeepMutable<ReadonlySet<{ readonly value: TaggedValues<number> }>>>()

// $ExpectType Map<{ _tag: string; value: string[]; }, Set<{ _tag: string; value: number[]; }>>
hole<Types.DeepMutable<ReadonlyMap<TaggedValues<string>, ReadonlySet<TaggedValues<number>>>>>()

// $ExpectType { _tag: string; value: { _tag: string; value: { _tag: string; value: boolean[]; }[]; }[]; }[]
hole<Types.DeepMutable<ReadonlyArray<TaggedValues<TaggedValues<TaggedValues<boolean>>>>>>()

// -------------------------------------------------------------------------------------
// MatchRecord
// -------------------------------------------------------------------------------------
Expand Down
21 changes: 21 additions & 0 deletions packages/effect/src/Types.ts
Expand Up @@ -170,6 +170,27 @@ export type Mutable<T> = {
-readonly [P in keyof T]: T[P]
}

/**
* Like `Types.Mutable`, but works recursively.
*
* @example
* import type * as Types from "effect/Types"
*
* type DeepMutableStruct = Types.DeepMutable<{
* readonly a: string;
* readonly b: readonly string[]
* }>
* // { a: string; b: string[] }
*
* @since 3.1.0
* @category types
*/
export type DeepMutable<T> = T extends ReadonlyMap<infer K, infer V> ? Map<DeepMutable<K>, DeepMutable<V>>
: T extends ReadonlySet<infer V> ? Set<DeepMutable<V>>
: T extends ReadonlyArray<infer V> ? Array<DeepMutable<V>>
: [keyof T] extends [never] ? T
: { -readonly [K in keyof T]: DeepMutable<T[K]> }

/**
* Avoid inference on a specific parameter
*
Expand Down

0 comments on commit ba64ea6

Please sign in to comment.