Hyperlinkv0.8.0-beta.28

Brand

Brand.Brandinterfaceeffect/Brand.ts:35
Brand<Keys>

A generic interface that defines a branded type.

When to use

Use to define a branded type such as number & Brand<"Positive"> when TypeScript should keep structurally identical values separate without changing their runtime value.

Source effect/Brand.ts:35169 lines
export interface Brand<in out Keys extends string> {
  readonly [TypeId]: {
    readonly [K in Keys]: Keys
  }
}

/**
 * A constructor for a branded type that provides validation and safe
 * construction methods.
 *
 * **When to use**
 *
 * Use as the shared callable interface for branded values when an API accepts
 * or returns a brand constructor and callers need throwing, `Option`, `Result`,
 * or type-guard validation forms.
 *
 * @see {@link nominal} for a constructor without runtime validation
 * @see {@link make} for creating a constructor from a validation predicate
 * @see {@link check} for creating a constructor from schema checks
 * @see {@link all} for combining brand constructors
 *
 * @category models
 * @since 2.0.0
 */
export interface Constructor<in out B extends Brand<any>> {
  /**
   * Constructs a branded type from a value of type `Unbranded<B>`, throwing an
   * error if the provided value is not valid.
   */
  (unbranded: Brand.Unbranded<B>): B
  /**
   * Constructs a branded type from a value of type `Unbranded<B>`, returning
   * `Some<B>` if the provided value is valid, `None` otherwise.
   */
  option(unbranded: Brand.Unbranded<B>): Option.Option<B>
  /**
   * Constructs a branded type from a value of type `Unbranded<B>`, returning
   * `Success<B>` if the provided value is valid, `Failure<BrandError>`
   * otherwise.
   */
  result(unbranded: Brand.Unbranded<B>): Result.Result<B, BrandError>
  /**
   * Attempts to refine the provided value of type `Unbranded<B>`, returning
   * `true` if the provided value is a valid branded type, `false` otherwise.
   */
  is(unbranded: Brand.Unbranded<B>): unbranded is Brand.Unbranded<B> & B

  /**
   * The checks that are applied to the branded type.
   *
   * @internal
   */
  checks?: readonly [SchemaAST.Check<Brand.Unbranded<B>>, ...Array<SchemaAST.Check<Brand.Unbranded<B>>>] | undefined
}

/**
 * Error returned when a branded type is constructed from an invalid value.
 *
 * **Details**
 *
 * The error wraps a `SchemaIssue.Issue`, exposes `message` through
 * `issue.toString()`, and formats as `BrandError(<message>)`.
 *
 * **Gotchas**
 *
 * `BrandError` is an error-like model with `_tag`, `name`, `message`, and
 * `toString`; it does not extend JavaScript `Error`.
 *
 * @category errors
 * @since 4.0.0
 */
export class BrandError {
  constructor(issue: SchemaIssue.Issue) {
    this.issue = issue
  }
  /**
   * Discriminant used to identify brand construction failures.
   *
   * @since 4.0.0
   */
  readonly _tag = "BrandError"
  /**
   * Error name used by tools that inspect JavaScript error-like objects.
   *
   * @since 4.0.0
   */
  readonly name: string = "BrandError"
  /**
   * Schema issue describing why brand validation failed.
   *
   * @since 4.0.0
   */
  readonly issue: SchemaIssue.Issue
  /**
   * Human-readable rendering of the validation issue.
   *
   * @since 4.0.0
   */
  get message() {
    return this.issue.toString()
  }
  /**
   * Formats the brand error together with its validation message.
   *
   * @since 4.0.0
   */
  toString() {
    return `BrandError(${this.message})`
  }
}

/**
 * Namespace containing type-level helpers for working with branded types and
 * brand constructors.
 *
 * @since 2.0.0
 */
export declare namespace Brand {
  /**
   * A utility type to extract a branded type from a `Constructor`.
   *
   * @category utility types
   * @since 2.0.0
   */
  export type FromConstructor<C> = C extends Constructor<infer B> ? B : never

  /**
   * A utility type to extract the unbranded value type from a brand.
   *
   * @category utility types
   * @since 2.0.0
   */
  export type Unbranded<B extends Brand<any>> = B extends infer U & Brands<B> ? U : B

  /**
   * A utility type to extract the keys of a branded type.
   *
   * @category utility types
   * @since 4.0.0
   */
  export type Keys<B extends Brand<any>> = keyof B[typeof TypeId]

  /**
   * A utility type to extract the brands from a branded type.
   *
   * @category utility types
   * @since 2.0.0
   */
  export type Brands<B extends Brand<any>> = Types.UnionToIntersection<
    { [K in Keys<B>]: K extends string ? Brand<K> : never }[Keys<B>]
  >

  /**
   * A utility type that checks that all brands have the same base type.
   *
   * @category utility types
   * @since 2.0.0
   */
  export type EnsureCommonBase<
    Brands extends readonly [Constructor<any>, ...Array<Constructor<any>>]
  > = {
    [B in keyof Brands]: Brand.Unbranded<Brand.FromConstructor<Brands[0]>> extends
      Brand.Unbranded<Brand.FromConstructor<Brands[B]>>
      ? Brand.Unbranded<Brand.FromConstructor<Brands[B]>> extends Brand.Unbranded<Brand.FromConstructor<Brands[0]>>
        ? Brands[B]
      : Brands[B]
      : "ERROR: All brands should have the same base type"
  }
}
Referenced by 7 symbols