-
-
Notifications
You must be signed in to change notification settings - Fork 573
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Sindre Sorhus <[email protected]>
- Loading branch information
1 parent
1c76afe
commit b29c31a
Showing
6 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type. | ||
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional. | ||
@example | ||
``` | ||
import {SetOptional} from 'type-fest'; | ||
type Foo = { | ||
a: number; | ||
b?: string; | ||
c: boolean; | ||
} | ||
type SomeOptional = SetOptional<Foo, 'b' | 'c'>; | ||
// type SomeOptional = { | ||
// a: number; | ||
// b?: string; // Was already optional and still is. | ||
// c?: boolean; // Is now optional. | ||
// } | ||
``` | ||
*/ | ||
export type SetOptional<BaseType, Keys extends keyof BaseType = keyof BaseType> = | ||
// Pick just the keys that are not optional from the base type. | ||
Pick<BaseType, Exclude<keyof BaseType, Keys>> & | ||
// Pick the keys that should be optional from the base type and make them optional. | ||
Partial<Pick<BaseType, Keys>> extends | ||
// If `InferredType` extends the previous, then for each key, use the inferred type key. | ||
infer InferredType | ||
? {[Property in keyof InferredType]: InferredType[Property]} | ||
: never; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type. | ||
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required. | ||
@example | ||
``` | ||
import {SetRequired} from 'type-fest'; | ||
type Foo = { | ||
a?: number; | ||
b: string; | ||
c?: boolean; | ||
} | ||
type SomeRequired = SetRequired<Foo, 'b' | 'c'>; | ||
// type SomeRequired = { | ||
// a?: number; | ||
// b: string; // Was already required and still is. | ||
// c: boolean; // Is now required. | ||
// } | ||
``` | ||
*/ | ||
export type SetRequired<BaseType, Keys extends keyof BaseType = keyof BaseType> = | ||
// Pick just the keys that are not required from the base type. | ||
Pick<BaseType, Exclude<keyof BaseType, Keys>> & | ||
// Pick the keys that should be required from the base type and make them required. | ||
Required<Pick<BaseType, Keys>> extends | ||
// If `InferredType` extends the previous, then for each key, use the inferred type key. | ||
infer InferredType | ||
? {[Property in keyof InferredType]: InferredType[Property]} | ||
: never; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {expectType, expectError} from 'tsd'; | ||
import {SetOptional} from '..'; | ||
|
||
// Update one required and one optional to optional. | ||
declare const variation1: SetOptional<{a: number; b?: string; c: boolean}, 'b' | 'c'>; | ||
expectType<{a: number; b?: string; c?: boolean}>(variation1); | ||
|
||
// Update two required to optional. | ||
declare const variation2: SetOptional<{a: number; b: string; c: boolean}, 'a' | 'b'>; | ||
expectType<{a?: number; b?: string; c: boolean}>(variation2); | ||
|
||
// Three optional remain optional. | ||
declare const variation3: SetOptional<{a?: number; b?: string; c?: boolean}, 'a' | 'b' | 'c'>; | ||
expectType<{a?: number; b?: string; c?: boolean}>(variation3); | ||
|
||
// Fail if type changes even if optional is right. | ||
declare const variation4: SetOptional<{a: number; b?: string; c: boolean}, 'b' | 'c'>; | ||
expectError<{a: boolean; b?: string; c?: boolean}>(variation4); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {expectType, expectError} from 'tsd'; | ||
import {SetRequired} from '..'; | ||
|
||
// Update one required and one optional to required. | ||
declare const variation1: SetRequired<{a?: number; b: string; c?: boolean}, 'b' | 'c'>; | ||
expectType<{a?: number; b: string; c: boolean}>(variation1); | ||
|
||
// Update two optional to required. | ||
declare const variation2: SetRequired<{a?: number; b?: string; c?: boolean}, 'a' | 'b'>; | ||
expectType<{a: number; b: string; c?: boolean}>(variation2); | ||
|
||
// Three required remain required. | ||
declare const variation3: SetRequired<{a: number; b: string; c: boolean}, 'a' | 'b' | 'c'>; | ||
expectType<{a: number; b: string; c: boolean}>(variation3); | ||
|
||
// Fail if type changes even if optional is right. | ||
declare const variation4: SetRequired<{a?: number; b: string; c?: boolean}, 'b' | 'c'>; | ||
expectError<{a?: boolean; b: string; c: boolean}>(variation4); |