TS: Как создать фабрику типов, используя строку для генерации ключей.

Я пытаюсь создать способ легко генерировать тип, который определяет множество ассоциаций ключевых значений с определенным шаблоном имени в ключах.

У меня есть конкретный тип, который очень повторяющийся, как и для любых метрик (работающих над аналитикой), у меня есть 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> &
    ...;
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
1
0
25
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете определить 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 и автоматически перенести их.

Вот ссылка на детскую площадку

Другие вопросы по теме