Skip to content

Commit

Permalink
feat(#135): add PartialExcept<T,P>
Browse files Browse the repository at this point in the history
  • Loading branch information
ashgw committed Oct 11, 2024
1 parent 2a88946 commit e84cc44
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Checkout the full [API reference](https://ts-roids.ashgw.me/) for all usage exam
- [`DeepPick<Obj,P>`](https://ts-roids.ashgw.me/types/DeepPick.html) - Deeply pick properties from a nested object, based on a given predicate `P`.
- [`EmptyObject`](https://ts-roids.ashgw.me/types/EmptyObject.html) - Represents any non-nullish value, basically `{}`.
- [`EqualStrlen<S1, S2>`](https://ts-roids.ashgw.me/types/EqualStrlen.html) - Check if two strings ``S1`` and ``S2`` have the same length.
- [`PartialExcept<T, P>`](https://ts-roids.ashgw.me/types/PartialExcept.html) - Makes all properties in `T` optional except those in `K` which remain required.
- [`FilterBy<Obj, P>`](https://ts-roids.ashgw.me/types/FilterBy.html) - Filters keys from the object type `Obj` based on a specified predicate ``P``.
- [`Flip<Obj>`](https://ts-roids.ashgw.me/types/Flip.html) - Flips keys with values of an object type `Obj`.
- [`Float<N>`](https://ts-roids.ashgw.me/types/Float.html) - Type representing a float.
Expand Down
24 changes: 22 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2250,5 +2250,25 @@ Any property marked as `NotIncluded` will be excluded from the resulting `OrderD
*/
export type Prune<T, N = NotIncluded> = OmitExactlyByTypeDeep<T, N>;

export type _PartialExcept<T, K extends keyof T> = Partial<Omit<T, K>> &
Required<Pick<T, K>>;
/**
* `PartialExcept<T, K extends keyof T>` is a utility type that makes all properties of `T` optional
* except for the properties specified in `K`, which are required. This is useful for scenarios where
* you want to enforce that certain fields must be present while allowing others to be omitted.
*
* @template T - The original type from which to derive the new type.
* @template K - A subset of keys from `T` that should remain required in the resulting type.
*
* @example
* ```ts
* type User = {
* id: number;
* name: string;
* email: string;
* };
*
* type UserUpdate = PartialExcept<User, 'email'>; // Result: { id?: number; name?: string; email: string; }
* ```
*/
export type PartialExcept<T, K extends keyof T> = {
[P in K]: T[P];
} & Partial<Omit<T, K>>;
31 changes: 31 additions & 0 deletions tests/partial-except.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Numeric, PartialExcept, Nullable, TestType } from 'src';
import { test, expect } from 'vitest';

type OneLevelDeep = {
foo: boolean;
bar?: Numeric;
baz: Nullable;
fooBaz: bigint;
bazFoo: string | boolean;
};

test('_', () => {
const result: TestType<
PartialExcept<OneLevelDeep, 'foo'>,
{
foo: boolean;
} & Partial<Omit<OneLevelDeep, 'foo'>>,
true
> = true;
expect(result).toBe(true);
});
test('_', () => {
const result: TestType<
PartialExcept<OneLevelDeep, 'bazFoo'>,
{
bazFoo: string | boolean;
} & Partial<Omit<OneLevelDeep, 'bazFoo'>>,
true
> = true;
expect(result).toBe(true);
});

0 comments on commit e84cc44

Please sign in to comment.