假设我有一个文字类型,定义为:

type MyKeys = 'a' | 'b' | 'c' | 'd'

我想声明一个类似于Record<MyKeys, number>的映射类型,只是我只想填写我的密钥的一个子集.(实际上,文字有大约20个值).

我希望避免Partial,因为它允许将潜在值指定为未定义.我想帮助开发人员确保,如果他们定义了一个值,那么它就是指定的.这在处理doing 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,
};

推荐答案

正如我的 comments 所暗示的那样,你不能真的做出一个可行的解决方案,所以你可以这样键入它,并让它正确地验证它:

const conf: ConfType = { ... };

但你能做的是有一个功能为你做到这一点:

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中,我们判断它是否是有效的配置对象.如果它扩展Partial<Record<MyKeys, number>>,并且在值中不包含undefined,那么它将返回C,否则它将给出有用的错误消息.

在下面的操场上测试这个解决方案:

Playground

Typescript相关问答推荐

接口DOMRouter选项未输出

将对象属性路径描述为字符串数组的类型

为什么在将条件返回类型的字符串赋给数字时没有类型错误?

angular 17独立使用多个组件(例如两个组件)

React typescribe Jest调用函数

扩展函数签名中的参数类型,而不使用泛型

输入元素是类型变体的对象数组的正确方法是什么?'

在映射类型中用作索引时,TypeScrip泛型类型参数无法正常工作

对未到达受保护路由的路由环境做出react

已解决:如何使用值类型限制泛型键?

使用Redux Saga操作通道对操作进行排序不起作用

为什么&Quot;元素隐式具有';Any';类型,因为...即使我已经打字了,也不能作为索引显示错误吗?

如何使这种一对一关系在旧表上起作用?

如何在try 运行独立的文字脚本Angular 项目时修复Visual Studio中的MODULE_NOT_FOUND

当传递带有或不带有参数的函数作为组件props 时,我应该如何指定类型?

如何使用angular15取消选中位于其他组件中的复选框

更漂亮的格式数组<;T>;到T[]

TypeScript是否不知道其他函数内部的类型判断?

为什么 Typescript 无法正确推断数组元素的类型?

Typescript 确保通用对象不包含属性