feat(typescript-types): Add OptionalKeysOf<T>
This commit is contained in:
@@ -14,8 +14,16 @@ The types included in this library are categorized by their purpose.
|
|||||||
| [`IsNever<T>`][] | `true` if `T` is `never`, `false` otherwise (`null`, `undefined`, `any` also yield `false`) |
|
| [`IsNever<T>`][] | `true` if `T` is `never`, `false` otherwise (`null`, `undefined`, `any` also yield `false`) |
|
||||||
| [`If<Test, TrueBranch, FalseBranch>`][] | Returns `TrueBranch` if `Test` is `true`, `FalseBranch` otherwise[^if_remark]. |
|
| [`If<Test, TrueBranch, FalseBranch>`][] | Returns `TrueBranch` if `Test` is `true`, `FalseBranch` otherwise[^if_remark]. |
|
||||||
|
|
||||||
[^if_remark]: Note the special behavior, if `boolean` is passed as `Test` the return value is a union of both branches, i.e. `TrueBranch | FalseBranch`.
|
[^if_remark]: If `boolean` is passed as `Test` the return value is a union of both branches, i.e. `TrueBranch | FalseBranch`.
|
||||||
|
|
||||||
[`IsAny<T>`]: src/is-any.ts
|
[`IsAny<T>`]: src/is-any.ts
|
||||||
[`IsNever<T>`]: src/is-never.ts
|
[`IsNever<T>`]: src/is-never.ts
|
||||||
[`If<Test, TrueBranch, FalseBranch>`]: src/if.ts
|
[`If<Test, TrueBranch, FalseBranch>`]: src/if.ts
|
||||||
|
|
||||||
|
#### Extraction Types
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| [`OptionalKeysOf<T>`][] | A union of all keys of `T` that are marked as optional. If `T` is a union, a union of the optional keys of all union members of `T` is returned. |
|
||||||
|
|
||||||
|
[`OptionalKeysOf<T>`]: src/optional-keys-of.ts
|
||||||
|
|||||||
5
packages/typescript-types/src/optional-keys-of.ts
Normal file
5
packages/typescript-types/src/optional-keys-of.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export type OptionalKeysOf<T extends object> = T extends unknown
|
||||||
|
? keyof {
|
||||||
|
[K in keyof T as {} extends Pick<T, K> ? K : never]: T[K]
|
||||||
|
}
|
||||||
|
: never
|
||||||
39
packages/typescript-types/test/optional-keys-of.tst.ts
Normal file
39
packages/typescript-types/test/optional-keys-of.tst.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import type { OptionalKeysOf } from '@/optional-keys-of.js'
|
||||||
|
import { expect } from 'tstyche'
|
||||||
|
|
||||||
|
interface Example1 {
|
||||||
|
requiredKey: number
|
||||||
|
optionalKey?: number
|
||||||
|
anotherOptional?: string
|
||||||
|
unknownNonOptionalKey: unknown
|
||||||
|
undefinedNonOptionalKey: undefined
|
||||||
|
neverKey: never
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Example2 {
|
||||||
|
requiredKey2: number
|
||||||
|
optionalKey2?: number
|
||||||
|
anotherOptional2?: string
|
||||||
|
unknownNonOptionalKey2: unknown
|
||||||
|
undefinedNonOptionalKey2: undefined
|
||||||
|
neverKey2: never
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExpectKeyOf<T, K extends keyof T> = { [P in K]: T[P] }
|
||||||
|
type KeysOfInGenericsPart<
|
||||||
|
Shape extends object,
|
||||||
|
Defaults extends Pick<Shape, OptionalKeysOf<Shape>>
|
||||||
|
> = Defaults
|
||||||
|
|
||||||
|
expect<OptionalKeysOf<Example1>>().type.toBe<'optionalKey' | 'anotherOptional'>()
|
||||||
|
expect<OptionalKeysOf<Example2>>().type.toBe<'optionalKey2' | 'anotherOptional2'>()
|
||||||
|
expect<OptionalKeysOf<Example1 | Example2>>().type.toBe<
|
||||||
|
'optionalKey' | 'anotherOptional' | 'optionalKey2' | 'anotherOptional2'
|
||||||
|
>()
|
||||||
|
|
||||||
|
expect<Pick<Example1, OptionalKeysOf<Example1>>>().type.toBe<
|
||||||
|
ExpectKeyOf<Example1, OptionalKeysOf<Example1>>
|
||||||
|
>()
|
||||||
|
|
||||||
|
type DefaultValues = { optionalKey: 1; anotherOptional2: 'asdf' }
|
||||||
|
expect<KeysOfInGenericsPart<Example1, DefaultValues>>().type.toBe<DefaultValues>()
|
||||||
Reference in New Issue
Block a user