UNPKG

mod-arch-shared

Version:

Shared UI components and utilities for modular architecture micro-frontend projects

147 lines 3.62 kB
/** * The type `{}` doesn't mean "any empty object", it means "any non-nullish value". * * Use the `AnyObject` type for objects whose structure is unknown. * * @see https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492 */ export type AnyObject = Record<string, unknown>; /** * Takes a type and makes all properties partial within it. * * TODO: Implement the SDK & Patch logic -- this should stop being needed as things will be defined as Patches */ export type RecursivePartial<T> = T extends object ? { [P in keyof T]?: RecursivePartial<T[P]>; } : T; /** * Partial only some properties. * * eg. PartialSome<FooBarBaz, 'foo' | 'bar'> */ export type PartialSome<Type, Keys extends keyof Type> = Pick<Partial<Type>, Keys> & Omit<Type, Keys>; /** * Unions all values of an object togethers -- antithesis to `keyof myObj`. */ export type ValueOf<T> = T[keyof T]; /** * Never allow any properties of `Type`. * * Utility type, probably never a reason to export. */ type Never<Type> = { [K in keyof Type]?: never; }; /** * Either TypeA properties or TypeB properties -- never both. * * @example * ```ts * type MyType = EitherNotBoth<{ foo: boolean }, { bar: boolean }>; * * // Valid usages: * const objA: MyType = { * foo: true, * }; * const objB: MyType = { * bar: true, * }; * * // TS Error -- can't have both properties: * const objBoth: MyType = { * foo: true, * bar: true, * }; * * // TS Error -- must have at least one property: * const objNeither: MyType = { * }; * ``` */ export type EitherNotBoth<TypeA, TypeB> = (TypeA & Never<TypeB>) | (TypeB & Never<TypeA>); /** * Either TypeA properties or TypeB properties or neither of the properties -- never both. * * @example * ```ts * type MyType = EitherOrBoth<{ foo: boolean }, { bar: boolean }>; * * // Valid usages: * const objA: MyType = { * foo: true, * }; * const objB: MyType = { * bar: true, * }; * const objBoth: MyType = { * foo: true, * bar: true, * }; * * // TS Error -- can't omit both properties: * const objNeither: MyType = { * }; * ``` */ export type EitherOrBoth<TypeA, TypeB> = EitherNotBoth<TypeA, TypeB> | (TypeA & TypeB); /** * Either TypeA properties or TypeB properties or neither of the properties -- never both. * * @example * ```ts * type MyType = EitherOrNone<{ foo: boolean }, { bar: boolean }>; * * // Valid usages: * const objA: MyType = { * foo: true, * }; * const objB: MyType = { * bar: true, * }; * const objNeither: MyType = { * }; * * // TS Error -- can't have both properties: * const objBoth: MyType = { * foo: true, * bar: true, * }; * ``` */ export type EitherOrNone<TypeA, TypeB> = EitherNotBoth<TypeA, TypeB> | (Never<TypeA> & Never<TypeB>); type Explode<T> = keyof T extends infer K ? K extends unknown ? { [I in keyof T]: I extends K ? T[I] : never; } : never : never; type AtMostOne<T> = Explode<Partial<T>>; type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K>; }> = Partial<T> & U[keyof U]; /** * Create a type where exactly one of multiple properties must be supplied. * * @example * ```ts * type Foo = ExactlyOne<{ a: number, b: string, c: boolean}>; * * // Valid usages: * const objA: Foo = { * a: 1, * }; * const objB: Foo = { * b: 'hi', * }; * const objC: Foo = { * c: true, * }; * * // TS Error -- can't have more than one property: * const objAll: Foo = { * a: 1, * b: 'hi', * c: true, * }; * ``` */ export type ExactlyOne<T> = AtMostOne<T> & AtLeastOne<T>; export {}; //# sourceMappingURL=typeHelpers.d.ts.map