Skip to content

Commit

Permalink
SetNonNullable: Fix usage in type predicate context (#515)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
  • Loading branch information
joealden and sindresorhus authored Nov 28, 2022
1 parent 055dedb commit 9bae03b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
15 changes: 5 additions & 10 deletions source/set-non-nullable.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import type {Except} from './except';
import type {Simplify} from './simplify';

/**
Create a type that makes the given keys non-nullable, where the remaining keys are kept as is.
Expand Down Expand Up @@ -35,10 +32,8 @@ type AllNonNullable = SetNonNullable<Foo>;
@category Object
*/
export type SetNonNullable<BaseType, Keys extends keyof BaseType = 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]>}
>;
export type SetNonNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> = {
[Key in keyof BaseType]: Key extends Keys
? NonNullable<BaseType[Key]>
: BaseType[Key];
};
12 changes: 12 additions & 0 deletions test-d/set-non-nullable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,15 @@ 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'>;
expectNotAssignable<{a: string; b: string}>(variation4);

// Update all keys if `Keys` generic is not passed.
declare const variation5: SetNonNullable<{a: number; b: string | undefined; c: boolean | null}>;
expectType<{a: number; b: string; c: boolean}>(variation5);

// Does not throw type error in type predicate contexts.
type Variation6Config = {a: boolean | null; b: boolean | null};
const variant6Fn = <TProp extends keyof Variation6Config>(
config: Variation6Config,
prop: TProp,
): config is SetNonNullable<Variation6Config, TProp> => Boolean(config[prop]);
expectNotAssignable<never>(variant6Fn); // Just to prevent unused error.

0 comments on commit 9bae03b

Please sign in to comment.