Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SetNonNullable type #431

Merged
merged 4 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export {Opaque, UnwrapOpaque} from './source/opaque';
export {InvariantOf} from './source/invariant-of';
export {SetOptional} from './source/set-optional';
export {SetRequired} from './source/set-required';
export {SetNonNullable} from './source/set-non-nullable';
export {ValueOf} from './source/value-of';
export {PromiseValue} from './source/promise-value';
export {AsyncReturnType} from './source/async-return-type';
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Click the type names for complete docs.
- [`InvariantOf`](source/invariant-of.d.ts) - Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes.
- [`SetOptional`](source/set-optional.d.ts) - Create a type that makes the given keys optional.
- [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required.
- [`SetNonNullable`](source/set-non-nullable.d.ts) - Create a type that makes the given keys non-nullable.
- [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from.
- [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type.
- [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type.
Expand Down
35 changes: 35 additions & 0 deletions source/set-non-nullable.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type {Except} from './except';
import type {Simplify} from './simplify';

/**
Create a type that makes the given keys non-nullable. The remaining keys are kept as is.

Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are non-nullable.

@example
```
import type {SetNonNullable} from 'type-fest';

type Foo = {
a: number;
b: string | undefined;
c?: boolean | null;
}

type SomeNonNullable = SetNonNullable<Foo, 'b' | 'c'>;
// type SomeNonNullable = {
// a: number;
// b: string; // Can no longer be undefined.
// c?: boolean; // Can no longer be null, but is still optional.
// }
```

@category Object
*/
export type SetNonNullable<BaseType, Keys extends keyof BaseType> =
Simplify<
// Pick just the keys that are readonly from the base type.
Except<BaseType, Keys> &
// Pick the keys that should be non-nullable from the base type and make them non-nullable.
{[Key in Keys]: NonNullable<BaseType[Key]>}
>;
18 changes: 18 additions & 0 deletions test-d/set-non-nullable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {expectType, expectError} from 'tsd';
import type {SetNonNullable} from '../index';

// Update one possibly undefined key and one possibly null key to non-nullable.
declare const variation1: SetNonNullable<{a: number; b: string | undefined; c: boolean | null}, 'b' | 'c'>;
expectType<{a: number; b: string; c: boolean}>(variation1);

// Update a key that is possibly null or undefined.
declare const variation2: SetNonNullable<{a: number; b: string | null | undefined}, 'b'>;
expectType<{a: number; b: string}>(variation2);

// Update an optional key.
declare const variation3: SetNonNullable<{a: number; b?: string | undefined}, 'b'>;
expectType<{a: number; b?: string}>(variation3);

// Fail if type changes even if non-nullable is right.
declare const variation4: SetNonNullable<{a: number; b: string | undefined}, 'b'>;
expectError<{a: string; b: string}>(variation4);