No existe una forma sencilla de crear una matriz de claves desde una interfaz. Los tipos se borran en tiempo de ejecución y los tipos de objetos (sin ordenar, con nombre) no se pueden convertir a tipos de tupla (ordenados, sin nombre) sin algún tipo de truco.
Opción 1: Aproximación 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 matriz simple (-), sin tupla (+ -) escritura manual con autocompletado
Extensión: Podríamos intentar ser elegantes y usar tipos recursivos para generar una tupla. Esto solo funcionó para mí para un par de accesorios (~ 5,6) hasta que el rendimiento se degradó enormemente. El tipo recursivo profundamente anidado tampoco es compatible oficialmente con TS: enumero este ejemplo aquí para completarlo.
Opción 2: generador de código basado en la API del compilador de 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
Después de compilar y ejecutar este archivo con tsc && node dist/mybuildstep.js, ./src/generated/IMyTable-keys.tsse genera un archivo con el siguiente contenido:
// ./src/generated/IMyTable-keys.ts
const keys = ["id","title","createdAt","isDeleted"] as const;
(+) solución automática (+) tipo de tupla exacta (-) requiere paso de compilación
PD: He elegido ts-morph, ya que es una alternativa simple a la API del compilador TS original.