diff --git a/.changeset/dull-shrimps-kneel.md b/.changeset/dull-shrimps-kneel.md new file mode 100644 index 0000000000..6e379c5a2b --- /dev/null +++ b/.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 diff --git a/packages/effect/dtslint/Types.ts b/packages/effect/dtslint/Types.ts index 8713e42ae4..bfdadcff8d 100644 --- a/packages/effect/dtslint/Types.ts +++ b/packages/effect/dtslint/Types.ts @@ -72,6 +72,30 @@ hole>() // $ExpectType { [x: string]: number; } hole>>() +// ------------------------------------------------------------------------------------- +// DeepMutable +// ------------------------------------------------------------------------------------- + +type TaggedValues = { + readonly _tag: string + readonly value: ReadonlyArray +} + +// $ExpectType [string, number, boolean, bigint] +hole<[Types.DeepMutable, Types.DeepMutable, Types.DeepMutable, Types.DeepMutable]>() + +// $ExpectType { [x: string]: number; } +hole>() + +// $ExpectType Set<{ value: { _tag: string; value: number[]; }; }> +hole }>>>() + +// $ExpectType Map<{ _tag: string; value: string[]; }, Set<{ _tag: string; value: number[]; }>> +hole, ReadonlySet>>>>() + +// $ExpectType { _tag: string; value: { _tag: string; value: { _tag: string; value: boolean[]; }[]; }[]; }[] +hole>>>>>() + // ------------------------------------------------------------------------------------- // MatchRecord // ------------------------------------------------------------------------------------- diff --git a/packages/effect/src/Types.ts b/packages/effect/src/Types.ts index 2b804b0bd2..1185152dad 100644 --- a/packages/effect/src/Types.ts +++ b/packages/effect/src/Types.ts @@ -170,6 +170,27 @@ export type Mutable = { -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 extends ReadonlyMap ? Map, DeepMutable> + : T extends ReadonlySet ? Set> + : T extends ReadonlyArray ? Array> + : [keyof T] extends [never] ? T + : { -readonly [K in keyof T]: DeepMutable } + /** * Avoid inference on a specific parameter *