nodejs-firestore
nodejs-firestore copied to clipboard
Export different FieldValue types
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 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.
arrayUnion
and arrayRemove
could take a generic, something like arrayUnion<T>(args: ...T) => ArrayFieldValue
.
I added a quick snippet of what I have to do to accomplish this.