Skip to content

Commit

Permalink
feat(types): IsRequiredKey, IfRequiredKey
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed May 24, 2023
1 parent bac20f5 commit 16e2738
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 6 deletions.
28 changes: 28 additions & 0 deletions src/types/__tests__/if-key-required.spec-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @file Type Tests - IfRequiredKey
* @module tutils/types/tests/unit-d/IfRequiredKey
*/

import type Author from '#fixtures/author.interface'
import type TestSubject from '../if-key-required'

describe('unit-d:types/IfRequiredKey', () => {
type False = false
type True = true

it('should equal False if IsRequiredKey<T, K> extends false', () => {
// Arrange
type K = 'email'

// Expect
expectTypeOf<TestSubject<Author, K, True, False>>().toEqualTypeOf<False>()
})

it('should equal True if IsRequiredKey<T, K> extends true', () => {
// Arrange
type K = 'first_name'

// Expect
expectTypeOf<TestSubject<Author, K, True, False>>().toEqualTypeOf<True>()
})
})
25 changes: 25 additions & 0 deletions src/types/__tests__/is-key-required.spec-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @file Type Tests - IsRequiredKey
* @module tutils/types/tests/unit-d/IsRequiredKey
*/

import type Author from '#fixtures/author.interface'
import type TestSubject from '../is-key-required'

describe('unit-d:types/IsRequiredKey', () => {
it('should equal false if K is not required property of T', () => {
// Arrange
type K = 'email'

// Expect
expectTypeOf<TestSubject<Author, K>>().toEqualTypeOf<false>()
})

it('should equal true if K is required property of T', () => {
// Arrange
type K = 'last_name'

// Expect
expectTypeOf<TestSubject<Author, K>>().toEqualTypeOf<true>()
})
})
27 changes: 27 additions & 0 deletions src/types/if-key-required.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @file Type Definitions - IfRequiredKey
* @module tutils/types/IfRequiredKey
*/

import type IndexSignature from './index-signature'
import type IsRequiredKey from './is-key-required'

/**
* Conditional type that resolves depending on whether or not `K` is a required
* property of `T`.
*
* @see {@linkcode IsRequiredKey}
*
* @template T - Type to evaluate
* @template K - Key to evaluate
* @template True - Type if `K` is required property
* @template False - Type if `K` is not required property
*/
type IfRequiredKey<T, K extends IndexSignature, True, False> = IsRequiredKey<
T,
K
> extends true
? True
: False

export type { IfRequiredKey as default }
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type { default as IfFunction } from './if-function'
export type { default as IfJsonPrimitive } from './if-json-primitive'
export type { default as IfOptionalKey } from './if-key-optional'
export type { default as IfExactOptionalKey } from './if-key-optional-exact'
export type { default as IfRequiredKey } from './if-key-required'
export type { default as IfNever } from './if-never'
export type { default as IfNil } from './if-nil'
export type { default as IfNull } from './if-null'
Expand All @@ -58,6 +59,7 @@ export type { default as IsFunction } from './is-function'
export type { default as IsJsonPrimitive } from './is-json-primitive'
export type { default as IsOptionalKey } from './is-key-optional'
export type { default as IsExactOptionalKey } from './is-key-optional-exact'
export type { default as IsRequiredKey } from './is-key-required'
export type { default as IsNever } from './is-never'
export type { default as IsNil } from './is-nil'
export type { default as IsNull } from './is-null'
Expand Down
19 changes: 19 additions & 0 deletions src/types/is-key-required.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @file Type Definitions - IsRequiredKey
* @module tutils/types/IsRequiredKey
*/

import type IndexSignature from './index-signature'
import type RequiredKeys from './keys-required'

/**
* Returns a boolean indicating if `K` is a required property of `T`.
*
* @template T - Type to evaluate
* @template K - Key to evaluate
*/
type IsRequiredKey<T, K extends IndexSignature> = K extends RequiredKeys<T>
? true
: false

export type { IsRequiredKey as default }
8 changes: 2 additions & 6 deletions src/types/keys-required.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
* @module tutils/types/RequiredKeys
*/

import type ObjectPlain from './object-plain'

/**
* Extracts all required keys from `T`.
*
* @todo support nested keys
*
* @template T - Object type to evaluate
* @template T - Type to evaluate
*/
type RequiredKeys<T extends ObjectPlain> = Exclude<
type RequiredKeys<T> = Exclude<
{ [K in keyof T]: T extends Record<K, T[K]> ? K : never }[keyof T],
undefined
>
Expand Down

0 comments on commit 16e2738

Please sign in to comment.