Não existe uma maneira fácil de criar um array de chaves a partir de uma interface. Os tipos são apagados em tempo de execução e os tipos de objetos (não ordenados, nomeados) não podem ser convertidos em tipos de tupla (ordenados, não nomeados) sem algum tipo de hack.
Opção 1: abordagem manual
// Record type ensures, we have no double or missing keys, values can be neglected
function createKeys(keyRecord: Record<keyof IMyTable, any>): (keyof IMyTable)[] {
return Object.keys(keyRecord) as any
}
const keys = createKeys({ isDeleted: 1, createdAt: 1, title: 1, id: 1 })
// const keys: ("id" | "title" | "createdAt" | "isDeleted")[]
(+) tipo de retorno de array simples (-), sem tupla (+ -) escrita manual com preenchimento automático
Extensão: podemos tentar ser extravagantes e usar tipos recursivos para gerar uma tupla. Isso só funcionou para mim por alguns adereços (~ 5,6) até o desempenho degradar enormemente. Tipos recursivos profundamente aninhados também não são oficialmente suportados pelo TS - listo este exemplo aqui para fins de completude.
Opção 2: gerador de código baseado na API do compilador TS ( ts-morph )
// ./src/mybuildstep.ts
import {Project, VariableDeclarationKind, InterfaceDeclaration } from "ts-morph";
const project = new Project();
// source file with IMyTable interface
const sourceFile = project.addSourceFileAtPath("./src/IMyTable.ts");
// target file to write the keys string array to
const destFile = project.createSourceFile("./src/generated/IMyTable-keys.ts", "", {
overwrite: true // overwrite if exists
});
function createKeys(node: InterfaceDeclaration) {
const allKeys = node.getProperties().map(p => p.getName());
destFile.addVariableStatement({
declarationKind: VariableDeclarationKind.Const,
declarations: [{
name: "keys",
initializer: writer =>
writer.write(`${JSON.stringify(allKeys)} as const`)
}]
});
}
createKeys(sourceFile.getInterface("IMyTable")!);
destFile.saveSync(); // flush all changes and write to disk
Depois de compilar e executar esse arquivo com tsc && node dist/mybuildstep.js, um arquivo ./src/generated/IMyTable-keys.tscom o seguinte conteúdo é gerado:
// ./src/generated/IMyTable-keys.ts
const keys = ["id","title","createdAt","isDeleted"] as const;
(+) solução automática (+) tipo de tupla exata (-) requer etapa de construção
PS: Eu escolhi ts-morph, pois é uma alternativa simples para a API do compilador TS original.