如何将Enum成员用作Record <s,o>类型的索引?

时间:2019-01-16 16:01:13

标签: typescript enums

对于一个库,我想允许用户通过一些预设来修改它的配置。我的想法是为Enum提供通过select函数导出的所有可能的预设。

不幸的是,由于类型检查器的某些奇怪行为,我无法完全记住它。

下面的代码确实提供了预设和选择方法,但是它需要一个“非法”的预设。当我删除它(a.1)时,类型检查器抱怨我的预设没有索引属性。或者,可以将该非法预设保留在枚举中,但这还要求Presets const具有添加了枚举值作为键的属性。

另一个问题是,我无法使用枚举来创建Presets const本身。当我取消注释(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 :(得分:0)

正如Titian Cernicova指出的那样,我使用的是较旧的Typescript编译器。 Eclipse允许您使用特定于项目的编译器,但忽略了调整项目配置。