The Puppet type system has currently no way of defining a type with the meaning "any value except undefined" and hence no way of differentiating between a missing value and a given value of any type (the existing Any type accepts undef values).
The problem becomes apparent when declaring a hash where certain entries must be present but the value is unrestricted.
Two improvements are needed in order to fully resolve this issue:
A new parameterized type NotUndef[T] should be added to reflect a type that is assignable from all types that T is assignable from except all types that are assignable from Undef. The parameter T is optional and defaults to Any. The default type will be especially useful when declaring untyped parameters that require a value (such as current Resource parameters that have no default).
It is not possible to parameterize Optional with a non empty string value. This is a shorthand notation for Optional[Enum[value]]. It is added for the purpose of shortening what has to be typed when an Optional type is used for keys in a Struct.
The key of a Struct member can currently only be a string. This is too limited since it's impossible to declare that an entry is required even when it's OK to pass undef as that entry's value. It's also not possible to declare that the entry is optional but if it's provided, it cannot be undef. The key should therefore accept a Type. The Type must be limited such that it must be possible to extract a non-empty string, i.e.an Enum with exactly one entry or a String that is inferred from a literal non-empty string. This type can then be wrapped in an NotUndef or Optional to explicitly declare if the entry is required or optional.
Keys declared as string literals will be automatically converted to their corresponding String type. If the value type of the entry is assignable from Undef, then that String type will be wrapped in a Optional. This special rule will only apply when keys are given as string literals.
test level: unit