nodejs-firestore icon indicating copy to clipboard operation
nodejs-firestore copied to clipboard

Export different FieldValue types

Open saiichihashimoto opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe. Having typescript types that are "loose" enough to be used where they aren't wanted leaves room for error. For example, if I type a firestore field to be an array in my runtime code, I must also allow FieldValue to let FieldValue.arrayUnion work, but that will open it up to FieldValue.increment as well, which defeats the typescript typing.

Describe the solution you'd like I'd like FieldValue.___ to return the different underlying types instead of returning the same type for all of its static operations, preferably having arrayUnion and arrayRemove to allow for generics to type it even further.

Describe alternatives you've considered ~~Augmenting the module to allow for it.~~ Augmenting the module isn't possible, since you can't redefine a property to be more specific in typescript. Instead, you would have to cast it to a custom type. Adds a burden to the project where Firestore could return a more specific type. It looks something like this:

export interface ArrayUnionTransform<T> extends FirestoreAdmin.FieldValue {
	elements: T[];
}

export interface ServerTimestampTransform extends FirestoreAdmin.FieldValue {
	type: 'ServerTimestampTransform';
}

export const arrayUnion = <T>(...args: T[]): ArrayUnionTransform<T> => FirestoreAdmin.FieldValue.arrayUnion(...args) as ArrayUnionTransform<T>;

export const serverTimestamp = (): ServerTimestampTransform => FirestoreAdmin.FieldValue.serverTimestamp() as ServerTimestampTransform;

saiichihashimoto avatar Jun 29 '21 01:06 saiichihashimoto

@saiichihashimoto Thanks for the suggestion! This is definitely something we can consider adding with our next breaking change release. How would you separate the different underlying types? I'm guessing a arrayUnion and arrayRemove would have the same underlying type, whereas increment and serverTimestamp would have different types as well.

Could you mock up a sample of how you intend to use this in a ts playground? That would be very helpful.

thebrianchen avatar Jun 30 '21 13:06 thebrianchen

arrayUnion and arrayRemove could take a generic, something like arrayUnion<T>(args: ...T) => ArrayFieldValue.

saiichihashimoto avatar Jun 30 '21 15:06 saiichihashimoto

I added a quick snippet of what I have to do to accomplish this.

saiichihashimoto avatar Jun 30 '21 19:06 saiichihashimoto