You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为嵌套NoSQL集合自动推断Collection类的TypeScript类型?

解决方案:自动推断嵌套NoSQL集合的TypeScript类型

要实现从构造函数参数自动推断ID键名、父集合类型,仅需手动指定自定义Id<>类型,无需额外传递其他泛型参数,可以通过调整泛型约束和构造函数的类型推断逻辑实现。以下是完整的类型定义:

declare const t: unique symbol;
export type Id<T> = string & { readonly [t]: T };

// 递归提取集合及其所有父集合的ID键值对类型
type DocumentIds<C> = 
  C extends Collection<infer IdType, infer ParentCollection, infer IdKey>
    ? { [K in IdKey]: IdType } & (ParentCollection extends void ? {} : DocumentIds<ParentCollection>)
    : never;

// 调整泛型顺序,让TypeScript自动推断IdKey和父集合类型
class Collection<
  IdType extends string = string,
  PC extends Collection | void = void,
  IdKey extends string = string
> {
  constructor(
    private readonly collectionName: string,
    private readonly idName: IdKey,
    private readonly parent?: PC
  ) {}

  getCollectionPath(
    ids: PC extends void ? void : DocumentIds<PC>
  ): string {}

  getDocumentPath(
    ids: DocumentIds<this>
  ): string {}

  parse(path: string): DocumentIds<this> {
    return null as any;
  }
}

// 自定义ID类型
type AccountId = Id<'Account'>;
type UserId = Id<'User'>;

// 根集合:仅需指定IdType,其余类型自动推断
const AccountCollection = new Collection<AccountId>('accounts', 'accountId');

// 子集合:仅需指定IdType,父集合类型和ID键名自动推断
const UserCollection = new Collection<UserId>('users', 'userId', AccountCollection);

// 测试用例
// 根集合获取集合路径,无需参数
AccountCollection.getCollectionPath(); // 返回 'accounts'

// 根集合获取文档路径,需传入accountId
AccountCollection.getDocumentPath({
  accountId: 'acc-1' as AccountId,
}); // 返回 'accounts/acc-1'

// 子集合获取集合路径,需传入父集合的accountId
UserCollection.getCollectionPath({
  accountId: 'acc-1' as AccountId,
}); // 返回 'accounts/acc-1/users'

// 子集合获取文档路径,需传入父集合ID和自身ID
UserCollection.getDocumentPath({
  accountId: 'acc-1' as AccountId,
  userId: 'usr-1' as UserId,
}); // 返回 'accounts/acc-1/users/usr-1'

// 解析路径返回强类型的ID键值对
const ids = UserCollection.parse('accounts/acc-1/users/usr-1');
// ids类型为 { accountId: AccountId; userId: UserId }

核心优化说明

  • 自动泛型推断:构造函数的idName参数会自动映射到IdKey泛型,parent参数会自动映射到PC泛型,因此创建集合实例时仅需手动指定自定义的Id<>类型即可。
  • 递归ID类型提取:DocumentIds类型递归遍历集合的父链,自动拼接所有层级的ID键值对类型,避免手动维护嵌套类型。
  • 简化方法类型:使用DocumentIds<this>统一方法的参数和返回类型,保证类型一致性的同时简化代码结构。

内容的提问来源于stack exchange,提问作者Dominic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:50:24