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