Home Explore Blog Models CI



nixpkgs

4th chunk of `nixos/doc/manual/development/option-types.section.md`
291d9f1d1cf457de143fa5134e0c8825f9697f9f21d36b010000000100000fc9
        keys, all keys are interpreted as option definitions in the
        `config` section. Enabling this option implicitly puts all
        attributes in the `config` section.

        With this option enabled, defining a non-`config` section
        requires using a function:
        `the-submodule = { ... }: { options = { ... }; }`.

`types.deferredModule`

:   Whereas `submodule` represents an option tree, `deferredModule` represents
    a module value, such as a module file or a configuration.

    It can be set multiple times.

    Module authors can use its value in `imports`, in `submoduleWith`'s `modules`
    or in `evalModules`' `modules` parameter, among other places.

    Note that `imports` must be evaluated before the module fixpoint. Because
    of this, deferred modules can only be imported into "other" fixpoints, such
    as submodules.

    One use case for this type is the type of a "default" module that allow the
    user to affect all submodules in an `attrsOf submodule` at once. This is
    more convenient and discoverable than expecting the module user to
    type-merge with the `attrsOf submodule` option.

## Union types {#sec-option-types-unions}

A union of types is a type such that a value is valid when it is valid for at least one of those types.

If some values are instances of more than one of the types, it is not possible to distinguish which type they are meant to be instances of. If that's needed, consider using a [sum type](#sec-option-types-sums).

`types.either` *`t1 t2`*

:   Type *`t1`* or type *`t2`*, e.g. `with types; either int str`.
    Multiple definitions cannot be merged.

`types.oneOf` \[ *`t1 t2`* ... \]

:   Type *`t1`* or type *`t2`* and so forth, e.g.
    `with types; oneOf [ int str bool ]`. Multiple definitions cannot be
    merged.

`types.nullOr` *`t`*

:   `null` or type *`t`*. Multiple definitions are merged according to
    type *`t`*.


## Sum types {#sec-option-types-sums}

A sum type can be thought of, conceptually, as a *`types.enum`* where each valid item is paired with at least a type, through some value syntax.
Nix does not have a built-in syntax for this pairing of a label and a type or value, so sum types may be represented in multiple ways.

If the you're interested in can be distinguished without a label, you may simplify your value syntax with a [union type](#sec-option-types-unions) instead.

`types.attrTag` *`{ attr1 = option1; attr2 = option2; ... }`*

:   An attribute set containing one attribute, whose name must be picked from
    the attribute set (`attr1`, etc) and whose value consists of definitions that are valid for the corresponding option (`option1`, etc).

    This type appears in the documentation as _attribute-tagged union_.

    Example:

    ```nix
    { lib, ... }:
    let inherit (lib) type mkOption;
    in {
      options.toyRouter.rules = mkOption {
        description = ''
          Rules for a fictional packet routing service.
        '';
        type = types.attrsOf (
          types.attrTag {
            bounce = mkOption {
              description = "Send back a packet explaining why it wasn't forwarded.";
              type = types.submodule {
                options.errorMessage = mkOption { … };
              };
            };
            forward = mkOption {
              description = "Forward the packet.";
              type = types.submodule {
                options.destination = mkOption { … };
              };
            };
            drop = types.mkOption {
              description = "Drop the packet without sending anything back.";
              type = types.submodule {};
            };
          });
      };
      config.toyRouter.rules = {
        http = {
          bounce = {
            errorMessage = "Unencrypted HTTP is banned. You must always use https://.";
          };
        };
        ssh = { drop = {}; };
      };
    }
    ```

## Composed types {#sec-option-types-composed}

Composed types are types that take a type as parameter. `listOf

Title: Deferred Modules, Union Types, and Sum Types
Summary
This section concludes the explanation of `types.deferredModule`, describing it as a module value for dynamic imports, shared configurations, and affecting multiple submodules at once. It then introduces "Union types," which allow a value to be valid if it matches at least one of several specified types. Specific union types covered are `types.either` (one of two types), `types.oneOf` (one of a list of types), and `types.nullOr` (null or a specified type). Following this, "Sum types" are introduced as a way to pair a label with a type or value, often used when values need explicit distinction. The primary example is `types.attrTag`, which expects an attribute set containing a single attribute whose name and value conform to a predefined option. The text ends by briefly mentioning "Composed types" as types that take another type as a parameter.