[英]Declare object with keys constrained to be element of object literal
假设我将文字类型定义为:
type MyKeys = 'a' | 'b' | 'c' | 'd'
我想声明一个类似于Record<MyKeys, number>
的映射类型,除了我只想填写我的键的一个子集。 (实际上,文字有大约 20 个值)。
我想避免使用Partial
,因为它允许将潜在值指定为未定义。 我想帮助开发人员确保如果他们定义了一个值,它就会被指定。 这在处理Object.entries
时也有帮助,因为它摆脱了对值的未定义处理。
这里的场景是我们有多种插件需要配置,但是不需要所有的字段。 所以像:
// Use another type instead of Partial<Record<...>>
type ConfigType = Partial<Record<MyKeys, number>>
const PluginA: ConfigType = {
a: undefined, // Would be legal with Partial, but I'd like to block this
b: 25
};
const PluginB: ConfigType = {
c: 13,
d: 52,
};
const PluginC: ConfigType = {
a: 12,
d: 42,
};
就像我的评论暗示的那样,您无法真正提出可行的解决方案,因此您可以像这样输入并让它正确验证:
const conf: ConfType = { ... };
但你可以做的是让 function 为你做这件事:
const conf = checked({ ... }); // errors at COMPILE TIME if invalid
让我们看看如何做到这一点:
type ConfInvalidError = [{ error: "Cannot pass undefined." }];
type ValidConf<C> = C extends Partial<Record<MyKeys, number>> ? undefined extends C[keyof C] ? ConfInvalidError : C : ConfInvalidError;
function checked<C>(conf: ValidConf<C>): C { return conf as C; }
TypeScript 将推断C
,然后将其传递给ValidConf
。
在ValidConf
中,我们检查它是否是一个有效的配置 object。如果它扩展了Partial<Record<MyKeys, number>>
并且在值中不包含undefined
,那么它将返回C
,否则它会给出一个有用的错误消息。
在下面的操场上测试这个解决方案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.