- `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 {