From f0b1c3faf6f4dcf7a6a71d4fa43c06d543c60df3 Mon Sep 17 00:00:00 2001 From: Davide Menegatti Date: Sun, 3 Jul 2022 21:53:48 +0200 Subject: [PATCH] Add `OptionalKeysOf`, `HasOptionalKeys`, `RequiredKeysOf`, `HasRequiredKeys` types (#405) Co-authored-by: Sindre Sorhus --- index.d.ts | 4 +++ readme.md | 4 +++ source/has-optional-keys.d.ts | 21 +++++++++++++ source/has-required-keys.d.ts | 59 +++++++++++++++++++++++++++++++++++ source/optional-keys-of.d.ts | 38 ++++++++++++++++++++++ source/required-keys-of.d.ts | 29 +++++++++++++++++ test-d/has-optional-keys.ts | 29 +++++++++++++++++ test-d/has-required-keys.ts | 29 +++++++++++++++++ test-d/optional-keys-of.ts | 29 +++++++++++++++++ test-d/required-keys-of.ts | 29 +++++++++++++++++ 10 files changed, 271 insertions(+) create mode 100644 source/has-optional-keys.d.ts create mode 100644 source/has-required-keys.d.ts create mode 100644 source/optional-keys-of.d.ts create mode 100644 source/required-keys-of.d.ts create mode 100644 test-d/has-optional-keys.ts create mode 100644 test-d/has-required-keys.ts create mode 100644 test-d/optional-keys-of.ts create mode 100644 test-d/required-keys-of.ts diff --git a/index.d.ts b/index.d.ts index 9f23234f6..af1ab44e8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -57,6 +57,10 @@ export { export {StringKeyOf} from './source/string-key-of'; export {Exact} from './source/exact'; export {ReadonlyTuple} from './source/readonly-tuple'; +export {OptionalKeysOf} from './source/optional-keys-of'; +export {HasOptionalKeys} from './source/has-optional-keys'; +export {RequiredKeysOf} from './source/required-keys-of'; +export {HasRequiredKeys} from './source/has-required-keys'; // Template literal types export {CamelCase} from './source/camel-case'; diff --git a/readme.md b/readme.md index b484871db..3cbf20a13 100644 --- a/readme.md +++ b/readme.md @@ -192,6 +192,10 @@ Click the type names for complete docs. - [`StringKeyOf`](source/string-key-of.d.ts) - Get keys of the given type as strings. - [`Schema`](source/schema.d.ts) - Create a deep version of another object type where property values are recursively replaced into a given value type. - [`Exact`](source/exact.d.ts) - Create a type that does not allow extra properties. +- [`OptionalKeysOf`](source/optional-keys-of.d.ts) - Extract all optional keys from the given type. +- [`HasOptionalKeys`](source/has-optional-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any optional fields. +- [`RequiredKeysOf`](source/required-keys-of.d.ts) - Extract all required keys from the given type. +- [`HasRequiredKeys`](source/has-required-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any required fields. ### JSON diff --git a/source/has-optional-keys.d.ts b/source/has-optional-keys.d.ts new file mode 100644 index 000000000..597e8aaa1 --- /dev/null +++ b/source/has-optional-keys.d.ts @@ -0,0 +1,21 @@ +import {OptionalKeysOf} from './optional-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any optional fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of optional fields. + +@example +``` +import type {HasOptionalKeys, OptionalKeysOf} from 'type-fest'; + +type UpdateService = { + removeField: HasOptionalKeys extends true + ? (field: OptionalKeysOf) => Promise + : never +} +``` + +@category Utilities +*/ +export type HasOptionalKeys = OptionalKeysOf extends never ? false : true; diff --git a/source/has-required-keys.d.ts b/source/has-required-keys.d.ts new file mode 100644 index 000000000..ec9daf368 --- /dev/null +++ b/source/has-required-keys.d.ts @@ -0,0 +1,59 @@ +import {RequiredKeysOf} from './required-keys-of'; + +/** +Creates a type that represents `true` or `false` depending on whether the given type has any required fields. + +This is useful when you want to create an API whose behavior depends on the presence or absence of required fields. + +@example +``` +import type {HasRequiredKeys} from 'type-fest'; + +type GeneratorOptions