UNPKG

type-plus

Version:
45 lines 1.86 kB
import type { NotExtendable } from './Extends.js'; import type { IsEmptyObject } from './IsEmptyObject.js'; /** * Can `A` assign to `B` * * Note that when union is involved, the assignability is measured distributively. * Meaning the result can be `Then | Else` (i.e. `boolean` by default), * instead of distinctive `Then` (`true`) or `Else` (`false`). * * This is the correct behavior. * * @example * ```ts * CanAssign<number | string, number> // boolean * ``` * * We are checking can `A` assign to `B`. * Since `A` is `number | string`, * `A` can assign to `B` when `A` is number` (true), and * `A` cannot assign to `B` when `A` is string` (false). * So the result is `true | false = boolean`. * * If you want to make sure all branches are assignable, * use `StrictCanAssign<A, B>`. */ export type CanAssign<A, B, Then = true, Else = false> = IsEmptyObject<A> extends true ? Record<string, unknown> extends B ? Then : Else : boolean extends A ? boolean extends B ? Then : Else : A extends B ? Then : Else; /** * Can `A` strictly assign to `B`. * * All branches in an union `A` are assignable to `B`. * * @example * ```ts * StrictCanAssign<number | string, number> // false * StrictCanAssign<number | string, number | string> // true * ``` */ export type StrictCanAssign<A, B, Then = true, Else = false> = IsEmptyObject<A> extends true ? Record<string, unknown> extends B ? Then : Else : boolean extends A ? boolean extends B ? Then : Else : [A] extends [B] ? Then : Else; /** * @deprecated use `CanAssign` instead */ export type IsAssign<A, B, Then = true, Else = false> = CanAssign<A, B, Then, Else>; export declare function canAssign<T>(canAssign: false): <S>(subject: NotExtendable<S, T>) => true; export declare function canAssign<T>(): <S extends T>(subject: S) => CanAssign<S, T>; //# sourceMappingURL=CanAssign.d.ts.map