Home > Net >  Dynamic key type with other key type in typescript
Dynamic key type with other key type in typescript

Time:03-18

How to make dynamic key with other static Key types in typescript. For Eg.

{
"organizationId": "NEW_ORG",
"displayName": "Test Display",
"photo": null,
"1645661283562_tab": {
    "isMove": false,
    "tabName": "Activities",
    }
}

I have a static type for other keys, but 1645661283562_tab is dynamic, how to make type for this type of object?

type RecordDto = {
  organizationId?: string;
  displayName?: string;
  photo?: string | null;
  [key: string]: { isMove:boolean, tabName: string };
};

this is not working. any solutions ?

CodePudding user response:

Ideally, split those off into a sub-object on RecordDto instead of having them directly on RecordDto. (For instance, a tabs property with the type Record<string, {isMove: boolean; tabName: string; }>.) But if you can't or don't want to do that:

Provided you can distinguish the index keys from the other keys based on their name, it will work as you have it with a slight tweak. For instance, your key is a number followed by _tab and none of your other properties fits that pattern, so a template literal type works for the key of the index signature and differentiates those from the other property names:

type RecordDto = {
    organizationId?: string;
    displayName?: string;
    photo?: string | null;
    [key: `${number}_tab`]: { isMove:boolean, tabName: string };
    //    ^^^^^^^^^^^^^^^
};

Playground link

If you're receiving these values as strings and need to use them to index into the type, you'll need to tell TypeScript they're valid for use as index keys. To do that, you can use either a type guard function:

function isValidTabName(name: string): name is `${number}_tab` {
    return /*...validation logic...*/;
}

...or a type assertion function:

function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
    if (! /*...validation logic...*/) {
        throw new Error(`The value "${name}" is not a valid tab key`);
    }
}

You use them like this:

function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
    assertIsValidTabName(tabKey);
    dto[tabKey] = {isMove, tabName};
}

(You'd use if (isValidTabName(tabKey)) if using the type guard function; the key is valid in the true branch.)

Playground link

  • Related