动态键类型与打字稿中的其他键类型

Dynamic key type with other key type in typescript

如何在打字稿中使用其他静态密钥类型制作动态密钥。 例如

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

我有其他键的静态类型,但是1645661283562_tab是动态的,如何为这种类型的对象创建类型?

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

这是行不通的。任何解决方案?

理想情况下,将它们拆分成 RecordDto 上的 sub-object,而不是直接放在 RecordDto 上。 (例如,类型为 Record<string, {isMove: boolean; tabName: string; }>tabs 属性。)但如果您不能或不想这样做:

如果您可以根据索引键的名称将索引键与其他键区分开来,只需稍微调整一下即可正常工作。例如,您的密钥是一个数字,后跟 _tab 并且您的其他属性的 none 符合该模式,因此 template literal type 适用于索引签名的密钥并将它们与其他属性区分开来属性 姓名:

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

Playground link

如果您以字符串的形式接收这些值并需要使用它们来对类型进行索引,则需要告诉 TypeScript 它们可以用作索引键。为此,您可以使用类型保护函数:

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

...或类型断言函数:

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

你这样使用它们:

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

(如果使用类型保护功能,您将使用 if (isValidTabName(tabKey));密钥在 true 分支中有效。)

Playground link