Không có cách nào dễ dàng để tạo một mảng khóa từ một giao diện. Các loại bị xóa trong thời gian chạy và các loại đối tượng (không có thứ tự, được đặt tên) không thể chuyển đổi thành các loại tuple (có thứ tự, không có tên) mà không có một số loại hack.
Tùy chọn 1: Cách tiếp cận thủ công
// 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")[]
(+) kiểu trả về mảng (-) đơn giản, không viết thủ công tuple (+ -) với tính năng tự động hoàn thành
Phần mở rộng: Chúng tôi có thể cố gắng trở nên lạ mắt và sử dụng các kiểu đệ quy để tạo một bộ tuple. Điều này chỉ phù hợp với tôi đối với một vài đạo cụ (~ 5,6) cho đến khi hiệu suất bị giảm sút hàng loạt. Kiểu đệ quy lồng nhau sâu cũng không được TS hỗ trợ chính thức - Tôi liệt kê ví dụ này ở đây vì mục đích đầy đủ.
Tùy chọn 2: Trình tạo mã dựa trên API trình biên dịch 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
Sau khi chúng tôi biên dịch và chạy tệp này với tsc && node dist/mybuildstep.js, một tệp ./src/generated/IMyTable-keys.tscó nội dung sau sẽ được tạo:
// ./src/generated/IMyTable-keys.ts
const keys = ["id","title","createdAt","isDeleted"] as const;
(+) giải pháp tự động (+) loại tuple chính xác (-) yêu cầu bước xây dựng
Tái bút: Tôi đã chọn ts-morph, vì nó là một giải pháp thay thế đơn giản cho API trình biên dịch TS gốc.