Как использовать член Enum в качестве индекса для типа Record <S, O>? - PullRequest
0 голосов
/ 16 января 2019

Для библиотеки я хочу разрешить пользователю изменять ее конфигурацию с помощью некоторых предустановок. Моя идея состоит в том, чтобы предоставить Enum все возможные пресеты, экспортированные с помощью функции select.

К сожалению, я не смог получить его полностью, как я думал, из-за странного поведения средства проверки типов.

Приведенный ниже код предоставляет предустановки и метод выбора, но для них требуется «недопустимая» предустановка. Когда я удаляю его (a.1), средство проверки типов жалуется, что мои предустановки не имеют свойства индекса. В качестве альтернативы можно сохранить эту недопустимую предустановку в перечислении, но для этого также необходимо, чтобы в presets const было добавлено свойство со значением перечисления в качестве ключа.

Другая проблема заключается в том, что я не могу использовать enum для создания констант Presets. Когда я раскомментирую (b.2), все остается в силе и функционирует, но когда я затем комментирую (b.1), средство проверки типов обнаруживает, что тип литерала несовместим (b.3)

Что я делаю не так?

export enum Preset
{
    EASY = 'one',
    DEFAULT = 'two',
    HARD = 'three',
    IMPOSSIBLE = 'do_not_use' // (a.1)
}

type Config = Record<'a' | 'b', number>
type PresetNames = Preset.DEFAULT | Preset.EASY | Preset.HARD
type ConfigByPreset = Record<PresetNames, Config>

/* (b.3)
 * [ts] Type '{ [x: string]: { a: number; b: number; }; one: { a: number; b: number; }; two: { a: number; b: nu...' 
 * is not assignable to type 'Record<PresetNames, Record<"a" | "b", number>>'.
 * Property 'three' is missing in type '{ [x: string]: { a: number; b: number; }; one: { a: number; b: number; }; 
 * two: { a: number; b: nu...'.
 */
const Presets: ConfigByPreset = {
    one: { a: 1, b: 101 },
    two: { a: 2, b: 201 },
    ['three']: { a: 3, b: 301 },        // (b.1)
    // [Preset.HARD]: { a: 4, b: 301 }, // (b.2)
}

const defaultConfig = Presets[Preset.DEFAULT]

export function selectPreset( preset: PresetNames ) 
{
    // (a.2) [ts] Element implicitly has an 'any' type because type 'Record<Preset, Record<"a" | "b", number>>' has no index signature.
    const selectedConfig = Presets[preset]
    const otherConfig = Presets['three']

    console.log( 'config = ', selectedConfig, otherConfig, defaultConfig )
}

selectPreset( Preset.EASY )

1 Ответ

0 голосов
/ 16 января 2019

Как указала Тициан Черникова, я просто использовал более старый компилятор Typescript.Eclipse позволяет вам использовать специфичный для проекта компилятор, но я не стал настраивать конфигурацию проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...