Created
August 26, 2021 06:06
-
-
Save dorzepowski/fcd9e4d927fe2f1a49928d51d09ba6bf to your computer and use it in GitHub Desktop.
Typescript type which allow to set a value only on one from listed fields.
This file contains hidden or 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
/** | |
* Make all properties in T optional except property with key U. | |
* | |
* @example | |
* type Example = OtherOptional<'a', { a: string; b: string; }> // { a: string; b?: never; } | |
*/ | |
export type OtherOptional<U extends keyof T, T> = Pick<T, U> & Partial<T>; | |
/** | |
* Make all properties in T disallowed (type never) except property with key U. | |
* | |
* @example | |
* type Example = OtherDisallowed<'a', { a: string; b: string; }> // { a: string; b: never; } | |
*/ | |
export type OtherDisallowed<U extends keyof T, T> = { [K in keyof T]: K extends U ? T[K] : never }; | |
/** | |
* Make type that allows objects with only one property from type T and not the rest. | |
* | |
* @example | |
* type Example = OneOf<{ red: string, green: string }> //{red: string; green?: never} | {red?: never; green: string} | |
* | |
* | |
* const example: Example = { red: 'some text' green: 'some text' } | |
* ~~~~~~~ | |
* // error TS2322: Type '{ red: string; green: string; }' is not assignable to type 'Example1'. | |
* // Type '{ red: string; green: string; }' is not assignable to type 'OtherDisallowed<"red", OtherOptional<"red", { red: string; green: string; }>>'. | |
* // Types of property 'green' are incompatible. | |
* // Type 'string' is not assignable to type 'never'. | |
*/ | |
export type OneOf<T> = { [K in keyof T]: OtherDisallowed<K, OtherOptional<K, T>> }[keyof T]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment