能否为最多支持10个实体的缓存函数编写TypeScript类型?
解决TypeScript缓存函数类型定义的重载问题
你的问题出在手动编写的重载逻辑无法正确匹配多实体配置,且重载顺序会干扰类型推断。我们可以用映射类型替代手动重载,简洁实现最多10个实体的类型支持,同时保证fields属性能正确推导返回类型。
修正后的类型定义
// 基础实体类型映射 type EntityMap = { users: User, companies: Company, } // 单个实体的配置结构 type EntityConfig<T extends object> = { ids: string[]; fields?: Array<keyof T>; }; // 根据配置推导单个实体的返回类型 type EntityResult<T extends object, C extends EntityConfig<T>> = C extends { fields: infer F extends Array<keyof T> } ? Record<string, Pick<T, F[number]>> : Record<string, T>; // 整体配置对象的类型 type CacheConfig = { [K in keyof EntityMap]?: EntityConfig<EntityMap[K]>; }; // 整体返回结果的映射类型 type CacheResult<C extends CacheConfig> = { [K in keyof C & keyof EntityMap]: EntityResult<EntityMap[K], C[K]>; }; // 限制配置最多包含10个不同实体 type LimitKeys<T, N extends number, A extends unknown[] = []> = A['length'] extends N ? T : LimitKeys<T & { [K in keyof T]?: never }, N, [...A, unknown]>; type Max10Entities = LimitKeys<CacheConfig, 10>; declare function useCache<C extends Max10Entities>(config: C): CacheResult<C>;
核心逻辑说明
- EntityConfig:统一单个实体的配置规则,
fields仅允许传入对应实体类型的键数组。 - EntityResult:根据配置中是否存在
fields,动态生成全量实体类型或指定字段的子集类型。 - CacheConfig & CacheResult:通过映射类型将输入配置直接映射为对应的返回结构,避免重载匹配问题。
- Max10Entities:通过递归交叉类型限制配置最多包含10个实体,满足需求。
使用示例
const { users, companies } = useCache({ users: { ids: ['1', '2'], }, companies: { ids: ['3', '4'], fields: ['title'], } }); // typeof users = Record<string, User>; // typeof companies = Record<string, Pick<Company, 'title'>>;
这种方式无需手动编写多个重载,类型推断更准确,同时满足最多10个实体的限制。
内容的提问来源于stack exchange,提问作者Aracturat
相关产品推荐
相关产品推荐

