Skip to content

Commit

Permalink
feat(#52): finish ImmutableKeys & MutableKeys
Browse files Browse the repository at this point in the history
  • Loading branch information
ashgw committed Apr 19, 2024
1 parent afa7bd8 commit 17482f9
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 60 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### Installation
```bash
npm i ts-roids
npm i --save-dev ts-roids
# or
pnpm i -D ts-roids
```

### Examples
Expand Down
102 changes: 43 additions & 59 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,40 +151,6 @@ export type DeepPartial<T> = {
[P in Keys<T>]?: DeepPartial<T[P]>;
};

type X = {
readonly a: () => 1;
readonly b: string;
readonly c: {
readonly d: boolean;
readonly e: {
readonly g: {
readonly h: {
readonly i: true;
readonly j: 's';
};
readonly k: 'hello';
};
};
};
};

type Expected = {
a: () => 1;
b: string;
c: {
d: boolean;
e: {
g: {
h: {
i: true;
j: 's';
};
k: 'hello';
};
};
};
};

/**
* A type that recursively mutates all the proprties within a given object type `T`.
*/
Expand All @@ -198,7 +164,6 @@ export type DeepMutable<T> = T extends UnknownFunction
* Checks if all the nested properties of a given object T is actually mutable.
*/
export type IsDeepMutable<T> = T extends DeepMutable<T> ? true : false;
export type ResultType = TestType<DeepMutable<X>, Expected, true>;

/**
* A type that recursively turns the proprties within a given object type `T` immutable.
Expand All @@ -215,9 +180,6 @@ export type DeepImmutable<T> = T extends UnknownFunction
* Checks if all the nested properties of a given object T is actually immutable.
*/
export type IsDeepImmutable<T> = T extends DeepImmutable<T> ? true : false;
export type ResultType1 = TestType<IsDeepImmutable<X>, true, true>;
export type ResultType2 = TestType<DeepImmutable<Expected>, X, true>;
export type ResultType3 = DeepImmutable<Expected>;

export type AlterKeyTypeWith<T, K extends Keys<T>, R> = Pick<
T,
Expand Down Expand Up @@ -314,36 +276,58 @@ export type DeepRequiredKeys<T> = {
[K in Keys<T>]-?: EmptyObject extends Pick<T, K> ? never : RequiredKeys<K>;
}[keyof T];

export type MutableKeys<T> = keyof {
[P in Keys<T> as Equals<Pick<T, P>, Readonly<Pick<T, P>>> extends true
/**
* Retrieves the keys that are mutable from an object of type T.
* @example
* ```typescript
* type ExampleType = {
* a: number;
* readonly b: string;
* c: {
* a: string;
* d: { readonly x: Nullable; v: Maybe<Newable> };
* };
* };
*
* type MutableKeysOfExampleType = MutableKeys<ExampleType>;
* // Result: 'a' | 'c'
* ```
*/
export type MutableKeys<T> = {
[P in Keys<T>]: Equals<Pick<T, P>, Readonly<Pick<T, P>>> extends true
? never
: P]: never;
};

export type Result3 = TestType<
MutableKeys<{ a: number; readonly b: string }>,
'a',
true
>;
: P;
}[Keys<T>];

export type ImmutableKeys<T> = keyof {
[P in Keys<T> as Equals<Pick<T, P>, Readonly<Pick<T, P>>> extends true
/**
* Retrieves the keys that are immutable (readonly) from an object of type T.
* @example
* ```typescript
* type ExampleType = {
* a: number;
* readonly b: string;
* c: {
* a: string;
* d: { readonly x: Nullable; v: Maybe<Newable> };
* };
* };
*
* type ImmutableKeysOfExampleType = ImmutableKeys<ExampleType>;
* // Result: 'b'
* ```
*/
export type ImmutableKeys<T> = {
[P in Keys<T>]: Equals<Pick<T, P>, Readonly<Pick<T, P>>> extends true
? P
: never]: never;
};

export type Result4 = TestType<
ImmutableKeys<{ a: number; readonly b: string }>,
'b',
true
>;
: never;
}[Keys<T>];

declare function _testType<T1, T2, E extends boolean>(): Equals<
Equals<T1, T2>,
E
>;
/**
* Represents a type validation utility to determine if two types match.
* Determines if two types match.
* @template T1 The first type to compare.
* @template T2 The second type to compare.
* @template Expected A boolean literal indicating whether `T1` should match `T2`.
Expand Down
18 changes: 18 additions & 0 deletions tests/immutable-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ImmutableKeys, Maybe, Nullable, TestType, Newable } from 'src';
import { test, expect } from 'vitest';

test('does not go deep', () => {
const result: TestType<
ImmutableKeys<{
a: number;
readonly b: string;
c: {
a: string;
d: { readonly x: Nullable; v: Maybe<Newable> };
};
}>,
'b',
true
> = true;
expect(result).toBe(true);
});
18 changes: 18 additions & 0 deletions tests/mutable-keys.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { MutableKeys, Maybe, Nullable, TestType, Newable } from 'src';
import { test, expect } from 'vitest';

test('does not go deep', () => {
const result: TestType<
MutableKeys<{
a: number;
readonly b: string;
c: {
a: string;
d: { readonly x: Nullable; v: Maybe<Newable> };
};
}>,
'a' | 'c',
true
> = true;
expect(result).toBe(true);
});

0 comments on commit 17482f9

Please sign in to comment.