Home > OS >  How to get string literal types from Record defined as const
How to get string literal types from Record defined as const

Time:07-26

I am able to infer types when I'm not using Record

export const TabsDefinition = {
dimensionDetails: [
  { name: 'general', label: 'General' },
  { name: 'settings', label: 'Settings' },
  { name: 'list', label: 'List' },
],
} as const;

type MyNames = typeof TabsDefinition.dimensionDetails[number]['name'];

With this approach MyNames is infered as "general" | "settings" | "list"

But I want to use type for array of items - so I created this

type Tab = {
  name: string;
  label: string;
};

export const TabsDefinition: Record<string, ReadonlyArray<Tab>> = {
  dimensionDetails: [
    { name: 'general', label: 'General' },
    { name: 'settings', label: 'Settings' },
    { name: 'list', label: 'List' },
  ],
} as const;

type MyNames = typeof TabsDefinition.dimensionDetails[number]['name'];

but then MyNames type is infered as string

CodePudding user response:

When you assign a const object literal to a variable of type Record<string, ReadonlyArray<Tab>> the information is lost - now the compiler assumes that TabsDefinition is can contain any value conforming to that type.

The solution is to keep the precise type of your object literal, but force TS to type check against Record<string, ReadonlyArray<Tab>>.

There is an open issue "satisfies" operator to ensure an expression matches some type designed precisely to address that need.

Until it lands in an official release, you can use a constrained identity function:

type Tab = {
  name: string;
  label: string;
};

function createTabsDefinition <T extends Record<string, ReadonlyArray<Tab>>>(def: T): T {
  return def;
}

export const TabsDefinition = createTabsDefinition({
  dimensionDetails: [
    { name: 'general', label: 'General' },
    { name: 'settings', label: 'Settings' },
    { name: 'list', label: 'List' },  
  ],
} as const);

type MyNames = typeof TabsDefinition.dimensionDetails[number]['name'];

Playground link

  • Related