Skip to content

Commit a152ffa

Browse files
committed
work
1 parent 852ded6 commit a152ffa

File tree

4 files changed

+80
-86
lines changed

4 files changed

+80
-86
lines changed

packages/firestore/src/lite-api/reference.ts

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,11 @@ import { FirestoreDataConverter } from './snapshot';
4141
import { NestedUpdateFields, Primitive } from './types';
4242

4343
/**
44-
* Document data (for use with {@link @firebase/firestore/lite#(setDoc:1)}) consists of fields mapped to
45-
* values.
44+
* Document data (for use with {@link @firebase/firestore/lite#(setDoc:1)}).
45+
* Must be an object with string keys.
4646
*/
47-
export interface DocumentData {
48-
/** A mapping between a field and its value. */
49-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
50-
[field: string]: any;
51-
}
47+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
48+
export type DocumentData = Record<string, any>;
5249

5350
/**
5451
* Similar to Typescript's `Partial<T>`, but allows nested fields to be
@@ -113,7 +110,7 @@ export type SetOptions =
113110
* and can be used to write, read, or listen to the location. The document at
114111
* the referenced location may or may not exist.
115112
*/
116-
export class DocumentReference<T = DocumentData> {
113+
export class DocumentReference<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData> {
117114
/** The type of this Firestore reference. */
118115
readonly type = 'document';
119116

@@ -129,7 +126,7 @@ export class DocumentReference<T = DocumentData> {
129126
/**
130127
* If provided, the `FirestoreDataConverter` associated with this instance.
131128
*/
132-
readonly converter: FirestoreDataConverter<T> | null,
129+
readonly converter: FirestoreDataConverter<AppType, DbType> | null,
133130
readonly _key: DocumentKey
134131
) {
135132
this.firestore = firestore;
@@ -157,8 +154,8 @@ export class DocumentReference<T = DocumentData> {
157154
/**
158155
* The collection this `DocumentReference` belongs to.
159156
*/
160-
get parent(): CollectionReference<T> {
161-
return new CollectionReference<T>(
157+
get parent(): CollectionReference<AppType, DbType> {
158+
return new CollectionReference<AppType, DbType>(
162159
this.firestore,
163160
this.converter,
164161
this._key.path.popLast()
@@ -175,26 +172,26 @@ export class DocumentReference<T = DocumentData> {
175172
* @param converter - Converts objects to and from Firestore.
176173
* @returns A `DocumentReference<U>` that uses the provided converter.
177174
*/
178-
withConverter<U>(converter: FirestoreDataConverter<U>): DocumentReference<U>;
175+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(converter: FirestoreDataConverter<NewAppType, NewDbType>): DocumentReference<NewAppType, NewDbType>;
179176
/**
180177
* Removes the current converter.
181178
*
182179
* @param converter - `null` removes the current converter.
183180
* @returns A `DocumentReference<DocumentData>` that does not use a converter.
184181
*/
185182
withConverter(converter: null): DocumentReference<DocumentData>;
186-
withConverter<U>(
187-
converter: FirestoreDataConverter<U> | null
188-
): DocumentReference<U> {
189-
return new DocumentReference<U>(this.firestore, converter, this._key);
183+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(
184+
converter: FirestoreDataConverter<NewAppType, NewDbType> | null
185+
): DocumentReference<NewAppType, NewDbType> {
186+
return new DocumentReference<NewAppType, NewDbType>(this.firestore, converter, this._key);
190187
}
191188
}
192189

193190
/**
194191
* A `Query` refers to a query which you can read or listen to. You can also
195192
* construct refined `Query` objects by adding filters and ordering.
196193
*/
197-
export class Query<T = DocumentData> {
194+
export class Query<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData> {
198195
/** The type of this Firestore reference. */
199196
readonly type: 'query' | 'collection' = 'query';
200197

@@ -212,7 +209,7 @@ export class Query<T = DocumentData> {
212209
/**
213210
* If provided, the `FirestoreDataConverter` associated with this instance.
214211
*/
215-
readonly converter: FirestoreDataConverter<T> | null,
212+
readonly converter: FirestoreDataConverter<AppType, DbType> | null,
216213
readonly _query: InternalQuery
217214
) {
218215
this.firestore = firestore;
@@ -224,7 +221,7 @@ export class Query<T = DocumentData> {
224221
* @param converter - `null` removes the current converter.
225222
* @returns A `Query<DocumentData>` that does not use a converter.
226223
*/
227-
withConverter(converter: null): Query<DocumentData>;
224+
withConverter(converter: null): Query<DocumentData, DocumentData>;
228225
/**
229226
* Applies a custom data converter to this query, allowing you to use your own
230227
* custom model objects with Firestore. When you call {@link getDocs} with
@@ -234,24 +231,24 @@ export class Query<T = DocumentData> {
234231
* @param converter - Converts objects to and from Firestore.
235232
* @returns A `Query<U>` that uses the provided converter.
236233
*/
237-
withConverter<U>(converter: FirestoreDataConverter<U>): Query<U>;
238-
withConverter<U>(converter: FirestoreDataConverter<U> | null): Query<U> {
239-
return new Query<U>(this.firestore, converter, this._query);
234+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(converter: FirestoreDataConverter<NewAppType, NewDbType>): Query<NewAppType, NewDbType>;
235+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(converter: FirestoreDataConverter<NewAppType, NewDbType> | null): Query<NewAppType, NewDbType> {
236+
return new Query<NewAppType, NewDbType>(this.firestore, converter, this._query);
240237
}
241238
}
242239

243240
/**
244241
* A `CollectionReference` object can be used for adding documents, getting
245242
* document references, and querying for documents (using {@link (query:1)}).
246243
*/
247-
export class CollectionReference<T = DocumentData> extends Query<T> {
244+
export class CollectionReference<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData> extends Query<AppType, DbType> {
248245
/** The type of this Firestore reference. */
249246
readonly type = 'collection';
250247

251248
/** @hideconstructor */
252249
constructor(
253250
firestore: Firestore,
254-
converter: FirestoreDataConverter<T> | null,
251+
converter: FirestoreDataConverter<AppType, DbType> | null,
255252
readonly _path: ResourcePath
256253
) {
257254
super(firestore, converter, newQueryForPath(_path));
@@ -274,12 +271,12 @@ export class CollectionReference<T = DocumentData> extends Query<T> {
274271
* A reference to the containing `DocumentReference` if this is a
275272
* subcollection. If this isn't a subcollection, the reference is null.
276273
*/
277-
get parent(): DocumentReference<DocumentData> | null {
274+
get parent(): DocumentReference<DocumentData, DocumentData> | null {
278275
const parentPath = this._path.popLast();
279276
if (parentPath.isEmpty()) {
280277
return null;
281278
} else {
282-
return new DocumentReference(
279+
return new DocumentReference<DocumentData, DocumentData>(
283280
this.firestore,
284281
/* converter= */ null,
285282
new DocumentKey(parentPath)
@@ -296,21 +293,19 @@ export class CollectionReference<T = DocumentData> extends Query<T> {
296293
* @param converter - Converts objects to and from Firestore.
297294
* @returns A `CollectionReference<U>` that uses the provided converter.
298295
*/
299-
withConverter<U>(
300-
converter: FirestoreDataConverter<U>
301-
): CollectionReference<U>;
296+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(
297+
converter: FirestoreDataConverter<NewAppType, NewDbType>
298+
): CollectionReference<NewAppType, NewDbType>;
302299
/**
303300
* Removes the current converter.
304301
*
305302
* @param converter - `null` removes the current converter.
306303
* @returns A `CollectionReference<DocumentData>` that does not use a
307304
* converter.
308305
*/
309-
withConverter(converter: null): CollectionReference<DocumentData>;
310-
withConverter<U>(
311-
converter: FirestoreDataConverter<U> | null
312-
): CollectionReference<U> {
313-
return new CollectionReference<U>(this.firestore, converter, this._path);
306+
withConverter(converter: null): CollectionReference<DocumentData, DocumentData>;
307+
withConverter<NewAppType = DocumentData, NewDbType extends DocumentData = NewAppType extends DocumentData ? NewAppType : DocumentData>(converter: FirestoreDataConverter<NewAppType, NewDbType> | null): CollectionReference<NewAppType, NewDbType> {
308+
return new CollectionReference<NewAppType, NewDbType>(this.firestore, converter, this._path);
314309
}
315310
}
316311

@@ -330,7 +325,7 @@ export function collection(
330325
firestore: Firestore,
331326
path: string,
332327
...pathSegments: string[]
333-
): CollectionReference<DocumentData>;
328+
): CollectionReference<DocumentData, DocumentData>;
334329
/**
335330
* Gets a `CollectionReference` instance that refers to a subcollection of
336331
* `reference` at the the specified relative path.
@@ -343,11 +338,11 @@ export function collection(
343338
* to a collection.
344339
* @returns The `CollectionReference` instance.
345340
*/
346-
export function collection(
347-
reference: CollectionReference<unknown>,
341+
export function collection<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
342+
reference: CollectionReference<AppType, DbType>,
348343
path: string,
349344
...pathSegments: string[]
350-
): CollectionReference<DocumentData>;
345+
): CollectionReference<DocumentData, DocumentData>;
351346
/**
352347
* Gets a `CollectionReference` instance that refers to a subcollection of
353348
* `reference` at the the specified relative path.
@@ -360,16 +355,16 @@ export function collection(
360355
* to a collection.
361356
* @returns The `CollectionReference` instance.
362357
*/
363-
export function collection(
364-
reference: DocumentReference,
358+
export function collection<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
359+
reference: DocumentReference<AppType, DbType>,
365360
path: string,
366361
...pathSegments: string[]
367-
): CollectionReference<DocumentData>;
368-
export function collection(
369-
parent: Firestore | DocumentReference<unknown> | CollectionReference<unknown>,
362+
): CollectionReference<DocumentData, DocumentData>;
363+
export function collection<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
364+
parent: Firestore | DocumentReference<AppType, DbType> | CollectionReference<AppType, DbType>,
370365
path: string,
371366
...pathSegments: string[]
372-
): CollectionReference<DocumentData> {
367+
): CollectionReference<DocumentData, DocumentData> {
373368
parent = getModularInstance(parent);
374369

375370
validateNonEmptyArgument('collection', 'path', path);
@@ -392,7 +387,7 @@ export function collection(
392387
ResourcePath.fromString(path, ...pathSegments)
393388
);
394389
validateCollectionPath(absolutePath);
395-
return new CollectionReference(
390+
return new CollectionReference<DocumentData, DocumentData>(
396391
parent.firestore,
397392
/* converter= */ null,
398393
absolutePath
@@ -417,7 +412,7 @@ export function collection(
417412
export function collectionGroup(
418413
firestore: Firestore,
419414
collectionId: string
420-
): Query<DocumentData> {
415+
): Query<DocumentData, DocumentData> {
421416
firestore = cast(firestore, Firestore);
422417

423418
validateNonEmptyArgument('collectionGroup', 'collection id', collectionId);
@@ -429,7 +424,7 @@ export function collectionGroup(
429424
);
430425
}
431426

432-
return new Query(
427+
return new Query<DocumentData, DocumentData>(
433428
firestore,
434429
/* converter= */ null,
435430
newQueryForCollectionGroup(collectionId)
@@ -452,7 +447,7 @@ export function doc(
452447
firestore: Firestore,
453448
path: string,
454449
...pathSegments: string[]
455-
): DocumentReference<DocumentData>;
450+
): DocumentReference<DocumentData, DocumentData>;
456451
/**
457452
* Gets a `DocumentReference` instance that refers to a document within
458453
* `reference` at the specified relative path. If no path is specified, an
@@ -468,11 +463,11 @@ export function doc(
468463
* a document.
469464
* @returns The `DocumentReference` instance.
470465
*/
471-
export function doc<T>(
472-
reference: CollectionReference<T>,
466+
export function doc<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
467+
reference: CollectionReference<AppType, DbType>,
473468
path?: string,
474469
...pathSegments: string[]
475-
): DocumentReference<T>;
470+
): DocumentReference<AppType, DbType>;
476471
/**
477472
* Gets a `DocumentReference` instance that refers to a document within
478473
* `reference` at the specified relative path.
@@ -485,16 +480,16 @@ export function doc<T>(
485480
* a document.
486481
* @returns The `DocumentReference` instance.
487482
*/
488-
export function doc(
489-
reference: DocumentReference<unknown>,
483+
export function doc<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
484+
reference: DocumentReference<AppType, DbType>,
490485
path: string,
491486
...pathSegments: string[]
492-
): DocumentReference<DocumentData>;
493-
export function doc<T>(
494-
parent: Firestore | CollectionReference<T> | DocumentReference<unknown>,
487+
): DocumentReference<DocumentData, DocumentData>;
488+
export function doc<AppType = DocumentData, DbType extends DocumentData = AppType extends DocumentData ? AppType : DocumentData>(
489+
parent: Firestore | CollectionReference<AppType, DbType> | DocumentReference<AppType, DbType>,
495490
path?: string,
496491
...pathSegments: string[]
497-
): DocumentReference {
492+
): DocumentReference<AppType, DbType> {
498493
parent = getModularInstance(parent);
499494

500495
// We allow omission of 'pathString' but explicitly prohibit passing in both
@@ -543,9 +538,9 @@ export function doc<T>(
543538
* @returns true if the references point to the same location in the same
544539
* Firestore database.
545540
*/
546-
export function refEqual<T>(
547-
left: DocumentReference<T> | CollectionReference<T>,
548-
right: DocumentReference<T> | CollectionReference<T>
541+
export function refEqual<AppType, DbType extends DocumentData>(
542+
left: DocumentReference<AppType, DbType> | CollectionReference<AppType, DbType>,
543+
right: DocumentReference<AppType, DbType> | CollectionReference<AppType, DbType>
549544
): boolean {
550545
left = getModularInstance(left);
551546
right = getModularInstance(right);
@@ -573,7 +568,7 @@ export function refEqual<T>(
573568
* @returns true if the references point to the same location in the same
574569
* Firestore database.
575570
*/
576-
export function queryEqual<T>(left: Query<T>, right: Query<T>): boolean {
571+
export function queryEqual<AppType, DbType extends DocumentData>(left: Query<AppType, DbType>, right: Query<AppType, DbType>): boolean {
577572
left = getModularInstance(left);
578573
right = getModularInstance(right);
579574

0 commit comments

Comments
 (0)