Я пытаюсь создать способ легко генерировать тип, который определяет множество ассоциаций ключевых значений с определенным шаблоном имени в ключах.
У меня есть конкретный тип, который очень повторяющийся, как и для любых метрик (работающих над аналитикой), у меня есть 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
и автоматически перенести их.