TIL: Type alias augmentation in TypeScript

Sep 20, 2021
TIL typescript type alias augmentation

The first thing to remember is type alias augmentation is not allowed. This means we need to use interfaces. I was trying to represent string literals using interfaces but I failed as you guess.

After hours of fighting with TS, I finally found a solution in GitHub.

It is hacky but works... Just make your type alias depends on keyof SomeInterface.

Solution 1

This was the original solution from GitHub. It only supports index types since we use keyof operator.

Declaration:

// packages/core/store/locale/locale.types.ts

export const CHANGE_LOCALE = "CHANGE_LOCALE";

export interface LocaleRegistry {}
export type Locale = keyof LocaleRegistry; // keys of LocaleRegistry

export interface LocaleAction {
  type: typeof CHANGE_LOCALE;
  payload: Locale;
}

export type LocaleState = Locale;

Augmentation:

// apps/admin/src/@types/akdeniz-core.d.ts

import "@akdeniz/core";

declare module "@akdeniz/core" {
  export interface LocaleRegistry {
    // write here your string literals
    tr;
    en;
  }
}

Solution 2

This one supports any type since we rely on values.

Declaration:

// packages/core/store/locale/locale.types.ts

export const CHANGE_LOCALE = "CHANGE_LOCALE";

export interface LocaleRegistry {}
export type Locale = LocaleRegistry[keyof LocaleRegistry]; // values of LocaleRegistry

export interface LocaleAction {
  type: typeof CHANGE_LOCALE;
  payload: Locale;
}

export type LocaleState = Locale;

Augmentation:

// apps/admin/src/@types/akdeniz-core.d.ts

import "@akdeniz/core";

declare module "@akdeniz/core" {
  export interface LocaleRegistry {
    // write here any type as value
    0: "tr";
    1: "en";
    2: number[];
    someRandomKey: Uint16Array;
  }
}

Or even better with helper interface Registry:

// packages/core/src/index.ts

// ...

export interface Registry<T> {
  readonly [n: number]: T;
}

// ...
// apps/admin/src/@types/akdeniz-core.d.ts

import { Registry } from "@akdeniz/core";

declare module "@akdeniz/core" {
  export interface LocaleRegistry extends Registry<"en" | "tr" | number[] | Uint16Array> {}
}