typescript - 根据另一个对象的属性在一个对象中键入属性(在 Typescript 中)
问题描述
我真的不知道我想要的是否可能。我已经尝试了一段时间,但现在我放弃并向社区寻求帮助。
我想要一个这样的配置对象:
const someConfig: ParameterDescriptions = {
someNumProperty: {
name: 'numPropert',
type: 'number',
defaultValue: 42,
},
someStrProperty: {
name: 'strPropert',
type: 'string',
defaultValue: 'some default value',
},
someBoolProperty: {
name: 'boolProperty',
type: 'boolean',
defaultValue: false,
},
};
然后是这样的对象:
interface MyState {
someNumProperty: number;
someStrProperty: string;
someBoolProperty: boolean;
}
我想强制它MyState
具有相同的属性someConfig
,但每个ParameterDesc
类型属性中提到的类型
ParameterDescriptions
看起来像这样:
export interface BaseParameterDesc {
name: string;
}
export interface NumberParameterDesc extends BaseParameterDesc {
type: 'number';
defaultValue?: number;
}
export interface StringParameterDesc extends BaseParameterDesc {
type: 'string';
defaultValue?: string;
}
export interface BooleanParameterDesc extends BaseParameterDesc {
type: 'boolean';
defaultValue?: boolean;
}
export type ParameterDesc =
NumberParameterDesc|StringParameterDesc|BooleanParameterDesc;
export type ParameterDescriptions = {
[key: string]: ParameterDesc;
};
但我不知道如何建立MyState
和 的实例之间的关系ParameterDescription
。
我的一个想法是让 MyState 实现一些试图强制执行此操作的 State 类型,但它并没有真正起作用
type State<PDesc extends ParameterDescriptions> = {
// The .type at the end does not work, but I don't know
// of alternatives
[property in keyof PDesc]: PDesc[property].type;
};
有任何想法吗?或者这是不可能的?
这篇文章中的所有代码都可以在这个Typescript Playground中找到
解决方案
我们需要解决的第一个问题是您定义的方式someConfig
实际上不会保留属性名称,它最终会成为一个可被任何字符串索引的变量。ParameterDescriptions
如果我们使用通用辅助函数,我们可以轻松地强制执行约束并保留实际的键值:
function createConfig<T extends ParameterDescriptions>(c: T): T {
return c;
}
const someConfig = createConfig({
someNumProperty: {
name: 'numPropert',
type: 'number',
defaultValue: 42,
},
someStrProperty: {
name: 'strPropert',
type: 'string',
defaultValue: 'some default value',
},
someBoolProperty: {
name: 'boolProperty',
type: 'boolean',
defaultValue: false,
},
});
现在someConfig
保留了键名,我们可以使用与您类似的方法,只是不能将type
属性直接用作类型,我们需要一个额外的类型来映射类型名称和类型(我们也可以使用条件类型,但这似乎更简单在这种情况下)
type TypeNamesToTypes = {
boolean: boolean;
string: string;
number: number;
}
type State<T extends ParameterDescriptions> = { [P in keyof T]: TypeNamesToTypes[T[P]['type']]}
type MyState = State<typeof someConfig> // same as = {someNumProperty: number;someStrProperty: string;someBoolProperty: boolean;}
游乐场链接
推荐阅读
- javascript - 如何在 Lodash 中将 _.pull() 与正则表达式一起使用?
- python - 创建必须创建游戏 LOTTO 的程序
- python - Pandas 数据框中列的 KeyError
- kubernetes - 如何计算每个节点上特定 pod CPU 使用率的百分比?
- python - 如何在 scipy 中实现 ILU 预处理器?
- google-sheets - 谷歌表格功能分组和连接行
- python - 如何写函数的导数
- c - 如何修复 swapBack 函数以获得我想要的结果?
- python - 将多个嵌套的 JSON 文件读入 Pandas DataFrame
- c++ - 指向类内部成员函数的C++函数指针