我正在尝试创建一种轻松生成类型的方法,该类型定义了与键中的特定名称模式关联的大量键值。
我有一个非常重复的特定类型,对于任何指标(用于分析),我有4个相关的键。
例如,对于firstPageVisible
,我将有firstPageVisibleMetrics
,firstPageVisibleCount
,firstPageVisibleMetricsPerDevices
,firstPageVisibleCountPerDevices
。
但由于我有很多指标,我希望有一些工厂使其更容易阅读。
我想象的是这样的:
type DetailedMetric<Type> = (
name: string,
) => {
[`${name}Metrics`]?: Type;
[`${name}Count`]?: number;
[`${name}MetricsPerDevices`]?: PerDeviceData<Type>;
[`${name}CountPerDevices`]?: PerDeviceData<number>;
};
但我有错误:A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
.
我找不到一个令人满意的方法来解决这个问题。
最后,我希望有这样的东西(或类似):
type StoryDataType = {
_id: string;
...;
} & DetailedMetric("firstPageVisible")<number> &
DetailedMetric("metric2")<number> &
DetailedMetric("metric3")<number> &
DetailedMetric("metric4")<number> &
...;
您可以这样定义DetailedMetrics
:
type DetailedMetric<Type, Name extends string> = {
[K in `${Name}Metrics`]?: Type
} & {
[K in `${Name}Count`]?: number
} & {
[K in `${Name}MetricsPerDevices`]?: PerDeviceData<Type>
} & {
[K in `${Name}CountPerDevices`]?: PerDeviceData<number>
}
游乐场
你可以在一个基本类型上进行映射,并使用一个相对较新的TypeScript特性,叫做键重映射,它允许你在你想要做的时候计算一个属性键。
type Base<T> = {
Metrics?: T;
Count?: number;
MetricsPerDevices?: number;
CountPerDevices?: number;
}
type DetailedMetric<Type> = <N extends string>(
name: N,
) => {
// Remap the name to be our generic `N`.
[Key in keyof Base<Type> as `${N}${Key}`]: Base<Type>[Key];
};
这样你就可以在我们的Base
类型中定义新的属性,并让它们自动延续。
这是一个游乐场链接