Skip to content

Commit 7ce6e22

Browse files
committed
Improve update function types
1 parent 2f00610 commit 7ce6e22

File tree

6 files changed

+1590
-47
lines changed

6 files changed

+1590
-47
lines changed

Diff for: src/index.ts

+256-39
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { firestore } from 'firebase-admin'
1+
import type { firestore } from 'firebase-admin'
2+
import type { TypesaurusUtils } from './utils'
23

34
export namespace Typesaurus {
45
class DocId {}
@@ -148,10 +149,7 @@ export namespace Typesaurus {
148149

149150
export type ModelNodeData<Model> = AnyModelData<Model, false>
150151

151-
// NOTE: For some reason this won't work: AnyModelData<Model, boolean>
152-
export type ModelData<Model> =
153-
| AnyModelData<Model, true>
154-
| AnyModelData<Model, false>
152+
export type ModelData<Model> = AnyModelData<Model, boolean>
155153

156154
export type AnyModelData<Model, ServerDateNullable extends boolean> = {
157155
[Key in keyof Model]: ModelField<Model[Key], ServerDateNullable>
@@ -197,7 +195,7 @@ export namespace Typesaurus {
197195
}
198196

199197
/**
200-
* The document reference type with Typesaurus document API.
198+
* The document reference type with Typesaurus document API.aaay
201199
*/
202200
export interface RichRef<Model> extends PlainRef<Model>, DocAPI<Model> {
203201
collection: RichCollection<
@@ -250,38 +248,39 @@ export namespace Typesaurus {
250248
}
251249

252250
/**
253-
*
254-
*/
255-
export type UpdateFields<Model> = UpdateField<Model>[]
256-
257-
/**
258-
*
251+
* The update field interface. It contains path to the property and property value.
259252
*/
260-
export type UpdateField<Model> = []
253+
export interface UpdateField<Model> {
254+
key: string | string[]
255+
value: any
256+
}
261257

262258
/**
263259
* The value types to use for update operation.
264260
*/
265261
export type UpdateValue<Model, Key> = Key extends keyof Model
266262
? Model[Key] extends infer Type
267263
? Type extends number
268-
? MaybeValueRemoveOr<Model, Key, ValueIncrement>
269-
: Type extends Array<any>
270-
? MaybeValueRemoveOr<Model, Key, ValueArrayUnion | ValueArrayRemove>
264+
? Model[Key] | MaybeValueRemoveOr<Model, Key, ValueIncrement>
265+
: Type extends Array<infer ItemType>
266+
?
267+
| Model[Key]
268+
| MaybeValueRemoveOr<Model, Key, ValueArrayUnion<ItemType>>
269+
| ValueArrayRemove<ItemType>
271270
: Type extends Date
272-
? MaybeValueRemoveOr<Model, Key, ValueServerDate>
273-
: MaybeValueRemove<Model, Key>
271+
? Model[Key] | MaybeValueRemoveOr<Model, Key, ValueServerDate>
272+
: Model[Key] | MaybeValueRemove<Model, Key>
274273
: never
275274
: never
276275

277276
/**
278277
* The value types to use for upset operation.
279278
*/
280-
export type UpsetValue<T> = T extends number
279+
export type UpsetValue<Type> = Type extends number
281280
? ValueIncrement
282-
: T extends Array<any>
283-
? ValueArrayUnion | ValueArrayRemove
284-
: T extends ServerDate
281+
: Type extends Array<infer ItemType>
282+
? ValueArrayUnion<ItemType> | ValueArrayRemove<ItemType>
283+
: Type extends ServerDate
285284
? ValueServerDate
286285
: never
287286

@@ -315,19 +314,19 @@ export namespace Typesaurus {
315314
/**
316315
* The array union value type. It holds the payload to union.
317316
*/
318-
export interface ValueArrayUnion {
317+
export interface ValueArrayUnion<Type> {
319318
__type__: 'value'
320319
kind: 'arrayUnion'
321-
values: any[]
320+
values: Type[]
322321
}
323322

324323
/**
325324
* The array remove value type. It holds the data to remove from the target array.
326325
*/
327-
export interface ValueArrayRemove {
326+
export interface ValueArrayRemove<Type> {
328327
__type__: 'value'
329328
kind: 'arrayRemove'
330-
values: any[]
329+
values: Type[]
331330
}
332331

333332
/**
@@ -346,13 +345,10 @@ export namespace Typesaurus {
346345
? ValueRemove | ValueType
347346
: ValueType
348347

349-
export type MaybeValueRemove<Model, Key extends keyof Model> = Partial<
350-
Pick<Model, Key>
351-
> extends Pick<Model, Key>
352-
? ValueRemove
353-
: Undefined<Model[Key]> extends Model[Key]
354-
? ValueRemove
355-
: never
348+
export type MaybeValueRemove<
349+
Model,
350+
Key extends keyof Model
351+
> = TypesaurusUtils.RequiredKey<Model, Key> extends true ? never : ValueRemove
356352

357353
export type Undefined<T> = T extends undefined ? T : never
358354

@@ -435,8 +431,229 @@ export namespace Typesaurus {
435431
limit(to: number): LimitQuery
436432
}
437433

438-
export interface WriteHelpers<Model> {
439-
serverDate: () => ValueServerDate
434+
export interface WriteHelpers<_Model> {
435+
serverDate(): ValueServerDate
436+
437+
remove(): ValueRemove
438+
439+
increment(value: number): ValueIncrement
440+
441+
arrayUnion<Type>(values: Type | Type[]): ValueArrayUnion<Type>
442+
443+
arrayRemove<Type>(values: Type | Type[]): ValueArrayRemove<Type>
444+
}
445+
446+
export interface UpdateHelpers<Model> extends WriteHelpers<Model> {
447+
field<Key1 extends keyof Model>(
448+
key: Key1,
449+
value: UpdateValue<Model, Key1>
450+
): UpdateField<Model>
451+
452+
field<
453+
Key1 extends keyof Model,
454+
Key2 extends keyof TypesaurusUtils.AllRequired<Model>[Key1]
455+
>(
456+
key1: Key1,
457+
key2: Key2,
458+
value: TypesaurusUtils.SafePath2<Model, Key1, Key2> extends true
459+
? UpdateValue<TypesaurusUtils.AllRequired<Model>[Key1], Key2>
460+
: never
461+
): UpdateField<Model>
462+
463+
// field<
464+
// Key1 extends keyof Model,
465+
// Key2 extends keyof Model[Key1],
466+
// Key3 extends keyof Model[Key1][Key2]
467+
// >(
468+
// key1: Key1,
469+
// key2: Key2,
470+
// key3: Key3,
471+
// value: TypesaurusUtils.SafePath2<Model, Key1, Key2> extends true
472+
// ? UpdateValue<Model[Key1][Key2], Key3>
473+
// : never
474+
// ): UpdateField<Model>
475+
476+
field<
477+
Key1 extends keyof Model,
478+
Key2 extends keyof TypesaurusUtils.AllRequired<Model>[Key1],
479+
Key3 extends keyof TypesaurusUtils.AllRequired<
480+
TypesaurusUtils.AllRequired<Model>[Key1]
481+
>[Key2]
482+
>(
483+
key1: Key1,
484+
key2: Key2,
485+
key3: Key3,
486+
value: TypesaurusUtils.SafePath3<Model, Key1, Key2, Key3> extends true
487+
? UpdateValue<
488+
TypesaurusUtils.AllRequired<
489+
TypesaurusUtils.AllRequired<Model>[Key1]
490+
>[Key2],
491+
Key3
492+
>
493+
: never
494+
): UpdateField<Model>
495+
496+
field<
497+
Key1 extends keyof Model,
498+
Key2 extends keyof TypesaurusUtils.AllRequired<Model>[Key1],
499+
Key3 extends keyof TypesaurusUtils.AllRequired<
500+
TypesaurusUtils.AllRequired<Model>[Key1]
501+
>[Key2],
502+
Key4 extends keyof TypesaurusUtils.AllRequired<
503+
TypesaurusUtils.AllRequired<
504+
TypesaurusUtils.AllRequired<Model>[Key1]
505+
>[Key2]
506+
>[Key3]
507+
>(
508+
key1: Key1,
509+
key2: Key2,
510+
key3: Key3,
511+
key4: Key4,
512+
value: TypesaurusUtils.SafePath4<
513+
Model,
514+
Key1,
515+
Key2,
516+
Key3,
517+
Key4
518+
> extends true
519+
? UpdateValue<
520+
TypesaurusUtils.AllRequired<
521+
TypesaurusUtils.AllRequired<
522+
TypesaurusUtils.AllRequired<Model>[Key1]
523+
>[Key2]
524+
>[Key3],
525+
Key4
526+
>
527+
: never
528+
): UpdateField<Model>
529+
530+
/*
531+
532+
field<
533+
Key1 extends keyof Model,
534+
Key2 extends keyof Model[Key1],
535+
Key3 extends keyof Model[Key1][Key2],
536+
Key4 extends keyof Model[Key1][Key2][Key3]
537+
>(
538+
key: readonly [Key1, Key2, Key3, Key4],
539+
value:
540+
| UpdateModel<Model[Key1][Key2][Key3][Key4]>
541+
| UpdateValue<Model[Key1][Key2][Key3], Key4>
542+
): UpdateField<Model>
543+
544+
field<
545+
Key1 extends keyof Model,
546+
Key2 extends keyof Model[Key1],
547+
Key3 extends keyof Model[Key1][Key2],
548+
Key4 extends keyof Model[Key1][Key2][Key3],
549+
Key5 extends keyof Model[Key1][Key2][Key3][Key4]
550+
>(
551+
key: readonly [Key1, Key2, Key3, Key4, Key5],
552+
value:
553+
| UpdateModel<Model[Key1][Key2][Key3][Key4][Key5]>
554+
| UpdateValue<Model[Key1][Key2][Key3][Key4], Key5>
555+
): UpdateField<Model>
556+
557+
field<
558+
Key1 extends keyof Model,
559+
Key2 extends keyof Model[Key1],
560+
Key3 extends keyof Model[Key1][Key2],
561+
Key4 extends keyof Model[Key1][Key2][Key3],
562+
Key5 extends keyof Model[Key1][Key2][Key3][Key4],
563+
Key6 extends keyof Model[Key1][Key2][Key3][Key4][Key5]
564+
>(
565+
key: readonly [Key1, Key2, Key3, Key4, Key5, Key6],
566+
value:
567+
| UpdateModel<Model[Key1][Key2][Key3][Key4][Key5][Key6]>
568+
| UpdateValue<Model[Key1][Key2][Key3][Key4][Key5], Key6>
569+
): UpdateField<Model>
570+
571+
field<
572+
Key1 extends keyof Model,
573+
Key2 extends keyof Model[Key1],
574+
Key3 extends keyof Model[Key1][Key2],
575+
Key4 extends keyof Model[Key1][Key2][Key3],
576+
Key5 extends keyof Model[Key1][Key2][Key3][Key4],
577+
Key6 extends keyof Model[Key1][Key2][Key3][Key4][Key5],
578+
Key7 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6]
579+
>(
580+
key: readonly [Key1, Key2, Key3, Key4, Key5, Key6, Key7],
581+
value:
582+
| UpdateModel<Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7]>
583+
| UpdateValue<Model[Key1][Key2][Key3][Key4][Key5][Key6], Key7>
584+
): UpdateField<Model>
585+
586+
field<
587+
Key1 extends keyof Model,
588+
Key2 extends keyof Model[Key1],
589+
Key3 extends keyof Model[Key1][Key2],
590+
Key4 extends keyof Model[Key1][Key2][Key3],
591+
Key5 extends keyof Model[Key1][Key2][Key3][Key4],
592+
Key6 extends keyof Model[Key1][Key2][Key3][Key4][Key5],
593+
Key7 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6],
594+
Key8 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7]
595+
>(
596+
key: readonly [Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8],
597+
value:
598+
| UpdateModel<Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8]>
599+
| UpdateValue<Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7], Key8>
600+
): UpdateField<Model>
601+
602+
field<
603+
Key1 extends keyof Model,
604+
Key2 extends keyof Model[Key1],
605+
Key3 extends keyof Model[Key1][Key2],
606+
Key4 extends keyof Model[Key1][Key2][Key3],
607+
Key5 extends keyof Model[Key1][Key2][Key3][Key4],
608+
Key6 extends keyof Model[Key1][Key2][Key3][Key4][Key5],
609+
Key7 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6],
610+
Key8 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7],
611+
Key9 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8]
612+
>(
613+
key: readonly [Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9],
614+
value:
615+
| UpdateModel<
616+
Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8][Key9]
617+
>
618+
| UpdateValue<
619+
Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8],
620+
Key9
621+
>
622+
): UpdateField<Model>
623+
624+
field<
625+
Key1 extends keyof Model,
626+
Key2 extends keyof Model[Key1],
627+
Key3 extends keyof Model[Key1][Key2],
628+
Key4 extends keyof Model[Key1][Key2][Key3],
629+
Key5 extends keyof Model[Key1][Key2][Key3][Key4],
630+
Key6 extends keyof Model[Key1][Key2][Key3][Key4][Key5],
631+
Key7 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6],
632+
Key8 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7],
633+
Key9 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8],
634+
Key10 extends keyof Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8][Key9]
635+
>(
636+
key: readonly [
637+
Key1,
638+
Key2,
639+
Key3,
640+
Key4,
641+
Key5,
642+
Key6,
643+
Key7,
644+
Key8,
645+
Key9,
646+
Key10
647+
],
648+
value:
649+
| UpdateModel<
650+
Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8][Key9][Key10]
651+
>
652+
| UpdateValue<
653+
Model[Key1][Key2][Key3][Key4][Key5][Key6][Key7][Key8][Key9],
654+
Key10
655+
>
656+
): UpdateField<Model>*/
440657
}
441658

442659
export interface SchemaHelpers {
@@ -656,7 +873,7 @@ export namespace Typesaurus {
656873

657874
update<Environment extends RuntimeEnvironment | undefined = undefined>(
658875
id: string,
659-
data: ($: WriteHelpers<Model>) => UpdateModel<Model>,
876+
data: ($: UpdateHelpers<Model>) => UpdateModel<Model>,
660877
options?: OperationOptions<Environment>
661878
): Promise<void>
662879

@@ -798,15 +1015,15 @@ export namespace Typesaurus {
7981015

7991016
update<Environment extends RuntimeEnvironment | undefined = undefined>(
8001017
id: string,
801-
data: UpdateModel<Model> | UpdateFields<Model>,
1018+
data: UpdateModel<Model>,
8021019
options?: { as: Environment }
8031020
): Promise<void>
8041021

8051022
update<Environment extends RuntimeEnvironment | undefined = undefined>(
8061023
id: string,
8071024
data: (
808-
$: WriteHelpers<Model>
809-
) => UpdateModel<Model> | UpdateFields<Model>,
1025+
$: UpdateHelpers<Model>
1026+
) => UpdateModel<Model> | UpdateField<Model> | UpdateField<Model>[],
8101027
options?: OperationOptions<Environment>
8111028
): Promise<void>
8121029

0 commit comments

Comments
 (0)