Skip to content

Commit

Permalink
Rename Mutable to Writable (#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
mfulton26 committed May 24, 2022
1 parent 08de69b commit 638d597
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 67 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Expand Up @@ -7,6 +7,7 @@ export * from './source/observable-like';
// Utilities
export {Except} from './source/except';
export {Mutable} from './source/mutable';
export {Writable} from './source/writable';
export {Merge} from './source/merge';
export {MergeExclusive} from './source/merge-exclusive';
export {RequireAtLeastOne} from './source/require-at-least-one';
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -161,7 +161,7 @@ Click the type names for complete docs.
### Utilities

- [`Except`](source/except.d.ts) - Create a type from an object type without certain keys. This is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys).
- [`Mutable`](source/mutable.d.ts) - Create a type that strips `readonly` from all or some of an object's keys. The inverse of `Readonly<T>`.
- [`Writable`](source/writable.d.ts) - Create a type that strips `readonly` from all or some of an object's keys. The inverse of `Readonly<T>`. Formerly named `Mutable`.
- [`Merge`](source/merge.d.ts) - Merge two types into a new type. Keys of the second type overrides keys of the first type.
- [`MergeExclusive`](source/merge-exclusive.d.ts) - Create a type that has mutually exclusive keys.
- [`RequireAtLeastOne`](source/require-at-least-one.d.ts) - Create a type that requires at least one of the given keys.
Expand Down
41 changes: 3 additions & 38 deletions source/mutable.d.ts
@@ -1,40 +1,5 @@
import type {Except} from './except';
import type {Simplify} from './simplify';
import type {Writable} from './writable';

/**
Create a type that strips `readonly` from all or some of an object's keys. Inverse of `Readonly<T>`.
This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are mutable.
@example
```
import type {Mutable} from 'type-fest';
type Foo = {
readonly a: number;
readonly b: readonly string[]; // To show that only the mutability status of the properties, not their values, are affected.
readonly c: boolean;
};
const mutableFoo: Mutable<Foo> = {a: 1, b: ['2'], c: true};
mutableFoo.a = 3;
mutableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type.
mutableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly.
type SomeMutable = Mutable<Foo, 'b' | 'c'>;
// type SomeMutable = {
// readonly a: number;
// b: readonly string[]; // It's now mutable. The type of the property remains unaffected.
// c: boolean; // It's now mutable.
// }
```
@category Object
*/
/** @deprecated @see Writable */
export type Mutable<BaseType, Keys extends keyof BaseType = keyof BaseType> =
Simplify<
// Pick just the keys that are not mutable from the base type.
Except<BaseType, Keys> &
// Pick the keys that should be mutable from the base type and make them mutable by removing the `readonly` modifier from the key.
{-readonly [KeyType in keyof Pick<BaseType, Keys>]: Pick<BaseType, Keys>[KeyType]}
>;
Writable<BaseType, Keys>;
40 changes: 40 additions & 0 deletions source/writable.d.ts
@@ -0,0 +1,40 @@
import type {Except} from './except';
import type {Simplify} from './simplify';

/**
Create a type that strips `readonly` from all or some of an object's keys. Inverse of `Readonly<T>`.
This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable.
@example
```
import type {Writable} from 'type-fest';
type Foo = {
readonly a: number;
readonly b: readonly string[]; // To show that only the mutability status of the properties, not their values, are affected.
readonly c: boolean;
};
const writableFoo: Writable<Foo> = {a: 1, b: ['2'], c: true};
writableFoo.a = 3;
writableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type.
writableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly.
type SomeWritable = Writable<Foo, 'b' | 'c'>;
// type SomeWritable = {
// readonly a: number;
// b: readonly string[]; // It's now writable. The type of the property remains unaffected.
// c: boolean; // It's now writable.
// }
```
@category Object
*/
export type Writable<BaseType, Keys extends keyof BaseType = keyof BaseType> =
Simplify<
// Pick just the keys that are not writable from the base type.
Except<BaseType, Keys> &
// Pick the keys that should be writable from the base type and make them writable by removing the `readonly` modifier from the key.
{-readonly [KeyType in keyof Pick<BaseType, Keys>]: Pick<BaseType, Keys>[KeyType]}
>;
28 changes: 0 additions & 28 deletions test-d/mutable.ts

This file was deleted.

28 changes: 28 additions & 0 deletions test-d/writable.ts
@@ -0,0 +1,28 @@
import {expectType, expectError} from 'tsd';
import type {Writable} from '../index';

type Foo = {
readonly a: number;
readonly b: string;
};

const ab: Writable<Foo> = {a: 1, b: '2'};
ab.a = 2;
const ab2: Writable<Readonly<Foo>> = ab;
ab2.a = 2;

// Update one writable and one readonly to writable, leaving one property unaffected.
declare const variation1: Writable<{readonly a: number; b: string; readonly c: boolean}, 'b' | 'c'>;
expectType<{readonly a: number; b: string; c: boolean}>(variation1);

// Update two readonly to writable, leaving one property unaffected.
declare const variation2: Writable<{readonly a: number; readonly b: string; readonly c: boolean}, 'a' | 'b'>;
expectType<{a: number; b: string; readonly c: boolean}>(variation2);

// Three writable remain writable.
declare const variation3: Writable<{a: number; b: string; c: boolean}, 'a' | 'b' | 'c'>;
expectType<{a: number; b: string; c: boolean}>(variation3);

// Check if type changes raise an error even if readonly and writable are applied correctly.
declare const variation4: Writable<{readonly a: number; b: string; readonly c: boolean}, 'b' | 'c'>;
expectError<{readonly a: boolean; b: string; c: boolean}>(variation4);

0 comments on commit 638d597

Please sign in to comment.