Is there a way to extend the submodule type itself in a NixOS module?
For example, consider the following scenario:
# module1.nix
let
t1 = types.submodule {
options = {
bar = mkOption {
type = types.int;
default = 1;
};
};
};
in
{ foo = mkOption { type = t1; }; };
# module2.nix
let
t2 = types.submodule ({ name, config, ... }: {
options = {
# This represents t2
baz = mkOption {
type = types.bool;
default = true;
};
};
});
in
{ foo = mkOption { type = t2; }; };
This approach results in the type of foo
becoming a merged submodule with both bar
and baz
options. However, I want to extend the submodule type t1
itself, rather than just merging the options.
Why do I want to do this? I’m trying to create a reusable options to kubenix which contains a set of kubenertes resource corresponding types as submodules.
However, I can’t extend, for example, Pod
by addding a new option gpu-enabled
without modifying the Pod
type definition itself. I wonder if I can extend rather than modify the original type definition.
What I’m aiming for is something like this:
# We don't have such a thing as typeDefs, but let's assume we do.
# module1.nix
typeDefs.fooType = types.submodule {
options = {
bar = mkOption { type = types.int; };
};
}
# module2.nix
typeDefs.fooType = types.submodule {
options = {
baz = mkOption { type = types.bool; };
};
}
{ cfg, types }: {
options = {
foo = mkOption { type = types.fooType; } # fooType = merged submodule with bar and baz
};
}
However, as far as I know, types in NixOS modules are just structural and anonymous values (without any global path), so this seems impossible. It appears that referring to the submodule type that I want to extend is not possible.
Is there a way to achieve this kind of type extension?
Alternatively, I’m thinking of creating a meta NixOS module that outputs a type, evaluating it, and then inserting the resulting model back into the module. Has there been any attempt at this kind of approach?