| 1 | /** |
| 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| 3 | * |
| 4 | * This source code is licensed under the MIT license found in the |
| 5 | * LICENSE file in the root directory of this source tree. |
| 6 | */ |
| 7 | |
| 8 | /** |
| 9 | * Remove particular keys from an object type: |
| 10 | * ``` |
| 11 | * Without<{foo: string, bar: string, baz: number}, 'bar' | 'baz'> => {foo: string} |
| 12 | * ``` |
| 13 | */ |
| 14 | export type Without<T, U> = {[P in Exclude<keyof T, keyof U>]?: never}; |
| 15 | |
| 16 | /** |
| 17 | * Given two object types, return a type allowing keys from either one but not both |
| 18 | * ``` |
| 19 | * ExclusiveOr({foo: string}, {bar: number}) -> allows {foo: 'a'}, {bar: 1}, but not {foo: 'a', bar: 1} or {} |
| 20 | * ``` |
| 21 | */ |
| 22 | export type ExclusiveOr<T, U> = T | U extends object |
| 23 | ? (Without<T, U> & U) | (Without<U, T> & T) |
| 24 | : T | U; |
| 25 | |
| 26 | /** |
| 27 | * Make every key of a type optional, and make its type undefined |
| 28 | * ``` |
| 29 | * AllUndefined<{foo: string}> => {foo?: undefined} |
| 30 | * ``` |
| 31 | */ |
| 32 | export type AllUndefined<T> = {[P in keyof T]?: undefined}; |
| 33 | |
| 34 | /** |
| 35 | * Make every key of the object NOT readonly. The opposite of Readonly<T>. |
| 36 | * ``` |
| 37 | * {readonly foo: string} -> {foo: string} |
| 38 | * ``` |
| 39 | */ |
| 40 | export type Writable<T> = {-readonly [P in keyof T]: T[P]}; |
| 41 | |
| 42 | export type Json = string | number | boolean | null | Json[] | {[key: string]: Json}; |
| 43 | |
| 44 | type UnionKeys<T> = T extends unknown ? keyof T : never; |
| 45 | type StrictUnionHelper<T, TAll> = T extends unknown |
| 46 | ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>> |
| 47 | : never; |
| 48 | /** |
| 49 | * Make a union type T be a strict union by making all keys required. |
| 50 | * This allows a discriminated union to have fields accessed without a cast. |
| 51 | * For example, |
| 52 | * ``` |
| 53 | * StrictUnion<{type: 'foo', foo: string} | {type: 'bar', bar: number}> => {type: 'foo' | 'bar', foo?: string, bar?: number} |
| 54 | * ``` |
| 55 | */ |
| 56 | export type StrictUnion<T> = StrictUnionHelper<T, T>; |
| 57 | |
| 58 | /** |
| 59 | * Construct a type with the properties of T except for those in type K, |
| 60 | * applicable to T being a union type. |
| 61 | * ``` |
| 62 | * UnionOmit<foo | bar, 'baz'> => Omit<foo, 'baz'> | Omit<bar, 'baz'> |
| 63 | * ``` |
| 64 | */ |
| 65 | export type UnionOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never; |
| 66 | |