2.0 KB66 lines
Blame
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 */
14export 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 */
22export 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 */
32export 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 */
40export type Writable<T> = {-readonly [P in keyof T]: T[P]};
41
42export type Json = string | number | boolean | null | Json[] | {[key: string]: Json};
43
44type UnionKeys<T> = T extends unknown ? keyof T : never;
45type 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 */
56export 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 */
65export type UnionOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
66