嵌套集合类型的Typescript spread参数

6ojccjat  于 2023-05-01  发布在  TypeScript
关注(0)|答案(1)|浏览(107)

我正在使用firestore数据库,并创建了一个模式来建模我的数据:

type FirestoreCollection<T> = {
  documentType: T;
  subcollections?: {
    [key: string]: FirestoreCollection<object>;
  };
};

type FirestoreSchema<
  T extends { [key: string]: U },
  U = FirestoreCollection<object>
> = T;

export type FirestoreModel = FirestoreSchema<{
  'chat-messages': {
    documentType: ChatMessage;
  };
  chats: {
    documentType: Chat;
    subcollections: {
      'chat-participants': {
        documentType: ChatParticipant;
      };
    };
  };
}>;

这个模型运行良好。
我想为一个函数创建一个类型,它将接受一个参数数组作为输入,其中每个参数看起来像这样:
{ collection: string, id: string }
然而,我希望我的函数知道当前参数是否不是前一个参数的子集合,因此抛出类型错误。
基本上,我希望函数像这样工作:

// This should work because its a valid root level document
getDocument(
  { collection: 'chat-messages', id: '123' }
);

// this should work, because 'chat-participants' is a subcollection of 'chats'
getDocument(
  { collection: 'chats', id: '123' }
  { collection: 'chat-participants', id: '456' }
);

// This should error, because 'chats' is not a subcollection of 'chat-messages'
getDocument(
  { collection: 'chat-messages', id: '123' },
  { collection: 'chats', id: '456' }
);

// This should error, because 'invalid' is not a collection at the root
getDocument({ collection: 'invalid', id: '123' })

有什么想法吗

5lhxktic

5lhxktic1#

您可以尝试使用以下类型:

type GetCollectionArgs<T = FirestoreModel> = {
  [K in keyof T]: [{collection: K, id: string}] | ('subcollections' extends keyof T[K] ? 
    [{collection: K, id: string}, ...GetCollectionArgs<T[K]['subcollections']>]
  : never)
}[keyof T]

使用方法:

const getDocument = (...args: GetCollectionArgs<FirestoreModel>) => {

}

playground

相关问题