如何在TypeScript中定义Table接口的任意未知键子集类型F?
解决方案
你可以通过让TypeScript自动推断泛型F的方式实现需求,无需给F设置默认值,而是利用fields数组的元素类型约束F为O的子集,同时让rows仅包含F对应的属性。
修改后的接口定义
interface Table<O extends object, F extends keyof O> { // 用readonly数组帮助TypeScript推断字面量类型,避免F被宽泛推断为keyof O fields: readonly F[]; // Pick<O, F>确保rows只包含O中F对应的属性,且类型与O一致 rows: Pick<O, F>[]; }
使用示例
// 定义原始对象类型 type User = { id: number; name: string; age: number }; // 创建实例时,TypeScript会自动根据fields推断F为'id' | 'name' const userTable: Table<User> = { fields: ['id', 'name'], rows: [ { id: 1, name: 'Alice' }, // 仅需包含fields指定的键,无需age { id: 2, name: 'Bob' } ] };
关键说明
- 无需手动指定
F,TypeScript会通过fields数组的元素自动推断出F是keyof O的子集。 Pick<O, F>替代原有的Record<F, {}>,既能保证rows只包含fields中的键,还能保留这些键在O中的原始类型,比Record更贴合实际需求。- 给
fields加上readonly修饰符,能让TypeScript更准确地推断出F的字面量联合类型(比如'id' | 'name'),而非宽泛的keyof User。
如果不需要保留O中属性的原始类型,只想让rows包含F对应的任意类型属性,也可以把Pick<O, F>换回Record<F, unknown>(推荐用unknown替代{},类型更安全)。
内容的提问来源于stack exchange,提问作者striderhobbit
相关产品推荐
相关产品推荐

