Home > Enterprise >  Typescript: record of KeyType -> value types
Typescript: record of KeyType -> value types

Time:11-30

I need to create a Typescript Record with the keys defined in an independent type and specific types for each value.

The keys are defined as follows:

// Keys must be available/iterable at runtime
const keys = ['a', 'b', 'c'] as const
export type Key = typeof keys[number]

Now I see two options, both flawed.

Option 1: repeat the keys and define the value types explicitly, as needed. Flaw: Structure isn't actually based on Key and they might deviate.

export type Structure1 = {
  a: number
  b: boolean
  c: string
}

Option 2: define a record from Key and lose the specific type information on the values:

export type Structure2 = Record<Key, number | boolean | string>

Is there a third option for a Structure3 that uses Key as the key type and an explicit value type per key?

CodePudding user response:

You can keep it DRY and enforce your interface keys like this (performance bonus: no extra runtime code):

TS Playground link

type EnforceKeys<Key extends string, T extends Record<Key, unknown>> = {
  [K in keyof T as K extends Key ? K : never]: T[K];
};

const keys = ['a', 'b', 'c'] as const;
type Key = typeof keys[number];

// Ok
type Structure1 = EnforceKeys<Key, {
  a: number;
  b: boolean;
  c: string;
}>;

// Ok, and extra properties are omitted
type Structure2 = EnforceKeys<Key, {
  a: number;
  b: boolean;
  c: string;
  d: number[]; // omitted from type
  e: boolean; // omitted from type
}>;

// Error: Property 'c' is missing in type... (2344)
type Structure3 = EnforceKeys<Key, {
  a: number;
  b: boolean;
}>;
  • Related