Home Explore Blog Models CI



nixpkgs

6th chunk of `nixos/doc/manual/development/option-types.section.md`
54032f160faf9f59b397bd407e965bebb6c606ac6db355650000000100000fac
    - `attrsWith { elemType = t; }` is equivalent to `attrsOf t`
    - `attrsWith { lazy = true; elemType = t; }` is equivalent to `lazyAttrsOf t`
    - `attrsWith { placeholder = "id"; elemType = t; }`

      Displays the option as `foo.<id>` in the manual.


`types.uniq` *`t`*

:   Ensures that type *`t`* cannot be merged. It is used to ensure option
    definitions are provided only once.

`types.unique` `{ message = m }` *`t`*

:   Ensures that type *`t`* cannot be merged. Prints the message *`m`*, after
    the line `The option <option path> is defined multiple times.` and before
    a list of definition locations.

`types.coercedTo` *`from f to`*

:   Type *`to`* or type *`from`* which will be coerced to type *`to`* using
    function *`f`* which takes an argument of type *`from`* and return a
    value of type *`to`*. Can be used to preserve backwards compatibility
    of an option if its type was changed.

## Submodule {#section-option-types-submodule}

`submodule` is a very powerful type that defines a set of sub-options
that are handled like a separate module.

It takes a parameter *`o`*, that should be a set, or a function returning
a set with an `options` key defining the sub-options. Submodule option
definitions are type-checked accordingly to the `options` declarations.
Of course, you can nest submodule option definitions for even higher
modularity.

The option set can be defined directly
([Example: Directly defined submodule](#ex-submodule-direct)) or as reference
([Example: Submodule defined as a reference](#ex-submodule-reference)).

Note that even if your submodule’s options all have a default value,
you will still need to provide a default value (e.g. an empty attribute set)
if you want to allow users to leave it undefined.

::: {#ex-submodule-direct .example}
### Directly defined submodule
```nix
{
  options.mod = mkOption {
    description = "submodule example";
    type =
      with types;
      submodule {
        options = {
          foo = mkOption { type = int; };
          bar = mkOption { type = str; };
        };
      };
  };
}
```
:::

::: {#ex-submodule-reference .example}
### Submodule defined as a reference
```nix
let
  modOptions = {
    options = {
      foo = mkOption { type = int; };
      bar = mkOption { type = int; };
    };
  };
in
{
  options.mod = mkOption {
    description = "submodule example";
    type = with types; submodule modOptions;
  };
}
```
:::

The `submodule` type is especially interesting when used with composed
types like `attrsOf` or `listOf`. When composed with `listOf`
([Example: Declaration of a list of submodules](#ex-submodule-listof-declaration)), `submodule` allows
multiple definitions of the submodule option set
([Example: Definition of a list of submodules](#ex-submodule-listof-definition)).

::: {#ex-submodule-listof-declaration .example}
### Declaration of a list of submodules
```nix
{
  options.mod = mkOption {
    description = "submodule example";
    type =
      with types;
      listOf (submodule {
        options = {
          foo = mkOption { type = int; };
          bar = mkOption { type = str; };
        };
      });
  };
}
```
:::

::: {#ex-submodule-listof-definition .example}
### Definition of a list of submodules
```nix
{
  config.mod = [
    {
      foo = 1;
      bar = "one";
    }
    {
      foo = 2;
      bar = "two";
    }
  ];
}
```
:::

When composed with `attrsOf`
([Example: Declaration of attribute sets of submodules](#ex-submodule-attrsof-declaration)), `submodule` allows
multiple named definitions of the submodule option set
([Example: Definition of attribute sets of submodules](#ex-submodule-attrsof-definition)).

::: {#ex-submodule-attrsof-declaration .example}
### Declaration of attribute sets of submodules
```nix
{
  options.mod = mkOption {
    description = "submodule example";
    type =
      with types;
      attrsOf (submodule {
        options = {
          foo = mkOption { type = int; };
          bar = mkOption { type = str; };

Title: The `submodule` Type and its Composition
Summary
This chunk begins by concluding the discussion on composed types, specifically detailing `types.attrsWith` for configuring attribute sets, `types.uniq` and `types.unique` for enforcing single definitions of an option (with `unique` allowing custom messages), and `types.coercedTo` for backward-compatible type changes. The main focus then shifts to introducing the `submodule` type, which is described as a powerful mechanism for defining nested sets of options that are handled like separate modules. It explains how submodules can be defined directly or by reference, can be nested, and their options are type-checked. It also highlights the importance of providing an empty default value if the submodule is optional. Finally, the chunk demonstrates the utility of `submodule` when composed with `types.listOf` to allow multiple submodule definitions and with `types.attrsOf` for defining multiple *named* instances of submodules, providing code examples for both scenarios.