TS:如何使用字符串创建类型工厂来生成键

TS : How to create a type factory using a string to generate the keys

我正在尝试创建一种方法来轻松生成一种类型,该类型定义了与键中特定名称模式关联的大量键值。

我有一个非常重复的特定类型,对于任何指标(用于分析),我有 4 个相关联的键。

例如,对于 firstPageVisible 指标,我将有 firstPageVisibleMetricsfirstPageVisibleCountfirstPageVisibleMetricsPerDevicesfirstPageVisibleCountPerDevices

但是由于我有很多指标,我希望有某种工厂可以使它更易于阅读。

我在想象这样的事情:

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> 
}

Playground

您可以映射到一个基本类型上,并使用称为 Key Remapping 的相对较新的 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 类型中定义新属性并自动继承它们。

Here's a playground link