-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Lexus Drumgold <[email protected]>
- Loading branch information
1 parent
ca855cb
commit ac95845
Showing
8 changed files
with
155 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* @file Type Tests - MergeDefaults | ||
* @module tutils/types/tests/unit-d/MergeDefaults | ||
*/ | ||
|
||
import type Author from '#fixtures/author.interface' | ||
import type EmptyArray from '../empty-array' | ||
import type Merge from '../merge' | ||
import type TestSubject from '../merge-defaults' | ||
|
||
describe('unit-d:types/MergeDefaults', () => { | ||
it('should equal T if U extends EmptyArray', () => { | ||
expectTypeOf<TestSubject<Author, EmptyArray>>().toEqualTypeOf<Author>() | ||
}) | ||
|
||
it('should equal T if U extends EmptyObject', () => { | ||
expectTypeOf<TestSubject<Author>>().toEqualTypeOf<Author>() | ||
}) | ||
|
||
it('should merge defaults into T if U extends ObjectAny', () => { | ||
// Arrange | ||
type U = { email: Lowercase<string>; first_name?: string } | ||
type Expected = Merge<Author, Omit<U, 'first_name'>> | ||
|
||
// Expect | ||
expectTypeOf<TestSubject<Author, U>>().toEqualTypeOf<Expected>() | ||
}) | ||
|
||
it('should merge defaults into T if U extends readonly ObjectAny[]', () => { | ||
// Arrange | ||
type U1 = { display_name: string; first_name?: string }[] | ||
type U2 = [{ display_name: string }, { first_name?: string }] | ||
type E1 = Merge<Author, Omit<U1[0], 'first_name'>> | ||
type E2 = Merge<Author, U2[0]> | ||
|
||
// Expect | ||
expectTypeOf<TestSubject<Author, U1>>().toEqualTypeOf<E1>() | ||
expectTypeOf<TestSubject<Author, U2>>().toEqualTypeOf<E2>() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @file Type Tests - Merge | ||
* @module tutils/types/tests/unit-d/Merge | ||
*/ | ||
|
||
import type Author from '#fixtures/author.interface' | ||
import type TestSubject from '../merge' | ||
import type Simplify from '../simplify' | ||
|
||
describe('unit-d:types/Merge', () => { | ||
it('should equal Simplify<Omit<T, keyof U> & U>', () => { | ||
// Arrange | ||
type T = Author | ||
type U = { display_name: string } | ||
type Expected = Simplify<Omit<T, keyof U> & U> | ||
|
||
// Expect | ||
expectTypeOf<TestSubject<T, U>>().toEqualTypeOf<Expected>() | ||
}) | ||
|
||
it('should equal T if U extends EmptyObject', () => { | ||
expectTypeOf<TestSubject<Author>>().toEqualTypeOf<Author>() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* @file Type Definitions - MergeDefaults | ||
* @module tutils/types/MergeDefaults | ||
*/ | ||
|
||
import type EmptyArray from './empty-array' | ||
import type EmptyObject from './empty-object' | ||
import type Head from './head' | ||
import type IfNever from './if-never' | ||
import type Merge from './merge' | ||
import type ObjectAny from './object-any' | ||
import type OneOrMany from './one-or-many' | ||
|
||
/** | ||
* Assigns properties from one or more source objects to target object `T` for | ||
* all optional properties in `T`. | ||
* | ||
* Source objects are applied from left to right. Once a property is set on `T`, | ||
* additional values of the same property are ignored if the property is no | ||
* longer optional. | ||
* | ||
* @template T - Target object | ||
* @template U - Source object or source object array | ||
*/ | ||
type MergeDefaults< | ||
T extends ObjectAny, | ||
U extends OneOrMany<Partial<T>> = EmptyObject | ||
> = U extends EmptyArray | EmptyObject | ||
? T | ||
: U extends Partial<T> | ||
? MergeDefaults<T, [U]> | ||
: U extends [infer H, ...infer Rest extends readonly ObjectAny[]] | ||
? Merge< | ||
T, | ||
{ | ||
[K in keyof H & keyof T]: T[K & keyof T] extends infer V | ||
? IfNever< | ||
Extract<V, undefined>, | ||
V, | ||
Exclude<V, H[K & keyof H] | undefined> | H[K & keyof H] | ||
> | ||
: never | ||
} | ||
> extends infer V extends ObjectAny | ||
? Rest extends readonly Partial<V>[] | ||
? MergeDefaults<V, Rest> | ||
: never | ||
: never | ||
: Head<U> extends infer S extends Partial<T> | ||
? MergeDefaults<T, [S]> | ||
: never | ||
|
||
export type { MergeDefaults as default } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @file Type Definitions - Merge | ||
* @module tutils/types/Merge | ||
*/ | ||
|
||
import type EmptyObject from './empty-object' | ||
import type ObjectAny from './object-any' | ||
import type Simplify from './simplify' | ||
|
||
/** | ||
* Merges two types into one. | ||
* | ||
* Keys of `U` override `T`. | ||
* | ||
* @template T - Target object | ||
* @template U - Source object | ||
*/ | ||
type Merge< | ||
T extends ObjectAny, | ||
U extends ObjectAny = EmptyObject | ||
> = U extends EmptyObject ? T : Simplify<Omit<T, keyof U> & U> | ||
|
||
export type { Merge as default } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters