如何将类属性转换为属性名称字符串数组类型?
解决TypeScript中类属性名称数组的类型定义问题
1. 正确定义SomeTableFields类型
要获取类的实例属性名称组成的字符串数组类型,正确写法是(keyof SomeTable)[](或等价的Array<keyof SomeTable>)。keyof SomeTable会自动提取类的实例属性(静态成员如tableName不会被包含,刚好符合你排除方法的需求)。
修正后的核心代码:
// Objection.js Model export class SomeTable implements Model { public static get tableName(): string { return 'someTable' } public id: string; public name: string; public age: number; // 注意:TypeScript无int类型,需用number } // 正确定义目标类型 type SomeTableFields = (keyof SomeTable)[]; // 函数定义 function getFromTable(id: string, fields?: SomeTableFields){ // ... } // 使用示例 getFromTable('1', ['id', 'name']) // 校验通过 getFromTable('1', ['id', 'someNonExistentField']) // 触发类型错误,符合预期
你之前的错误是把(keyof SomeTable)[]误写为keyof SomeTable[]——后者取的是数组类型的键(比如push、length等数组方法/属性),完全不符合需求,因此会出现类型不匹配的报错。
2. 解决服务接口暴露时的类型错误
你的补充代码中,服务接口的参数定义存在冗余嵌套:SomeTableFields本身已是数组类型,无需再套一层[]。同时需修正函数参数名不匹配的问题,修正后代码如下:
// 假设GetFromTableResponse已定义 type GetFromTableResponse = { /* ... */ }; type WorkspaceService = SomeService; export interface SomeService { getFromTable: (id: string, fields?: SomeTableFields) => GetFromTableResponse; } export async function createSomeService(): Promise<WorkspaceService> { return { getFromTable: (id, selectFields) => getFromTable(id, selectFields) }; }
之前的Type 'string' is not assignable to type 'SomeTableFields'错误,本质是因为你把SomeTableFields(一维数组)定义成了二维数组,导致传入的一维数组无法匹配类型。修正后参数结构与实际传入值一致,报错即可消除。
3. 额外:严格排除实例方法(可选)
如果你的类后续会添加实例方法,想要彻底只保留数据属性,可以用条件类型过滤方法属性:
type ExcludeMethods<T> = { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]; // 此时SomeTableFields仅包含非方法的实例属性 type SomeTableFields = ExcludeMethods<SomeTable>[];
内容的提问来源于stack exchange,提问作者nonethewiser
相关产品推荐
相关产品推荐

