Il n'y a pas de moyen simple de créer un tableau de clés à partir d'une interface. Les types sont effacés au moment de l'exécution et les types d'objets (non ordonnés, nommés) ne peuvent pas être convertis en types tuple (ordonnés, sans nom) sans une sorte de piratage.
Option 1: approche manuelle
// 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")[]
(+) type de retour de tableau simple (-), pas d'écriture manuelle de tuple (+ -) avec auto-complétion
Extension: Nous pourrions essayer d'être sophistiqués et utiliser des types récursifs pour générer un tuple. Cela n'a fonctionné pour moi que pour quelques accessoires (~ 5,6) jusqu'à ce que les performances se dégradent massivement. Les types récursifs profondément imbriqués ne sont pas non plus officiellement pris en charge par TS - je liste cet exemple ici par souci d'exhaustivité.
Option 2: Générateur de code basé sur l'API du compilateur 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
Après avoir compilé et exécuté ce fichier avec tsc && node dist/mybuildstep.js, un fichier ./src/generated/IMyTable-keys.tsavec le contenu suivant est généré:
// ./src/generated/IMyTable-keys.ts
const keys = ["id","title","createdAt","isDeleted"] as const;
(+) solution automatique (+) type de tuple exact (-) nécessite une étape de construction
PS: J'ai choisi ts-morph, car c'est une alternative simple à l'API du compilateur TS d'origine.