M.Lewis
M.Lewis

Reputation: 1041

How to map an a Firestore array value defined as a FieldValue

I'm a bit stuck as to how to define an array value within my TypeScript interface for a Firestore document, whilst also taking advantage of FieldValue.arrayUnion(). Dependencies: TypeScript 3.7.2 and @google-cloud/firestore 2.6.0.

ie. The interface includes a 'members' key which is an array of strings:

import * as firestore from "@google-cloud/firestore";

interface SomeDoc {
  members: string[] | firestore.FieldValue;
}

const foo: SomeDoc = {
  members: ["s"]
};

const bar = foo.members.includes("s") ? "does include" : "does not include";

I can successfully update the value using the Firestore's FieldValue arrayUnion() and arrayRemove() methods, which is great. However TypeScript throws the following type error:

TypeScript error:
Property 'includes' does not exist on type 'string[] | FieldValue'.
  Property 'includes' does not exist on type 'FieldValue'.  TS2339

Anyone have any hints on how to best define this sort of value?

Upvotes: 0

Views: 437

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317467

TypeScript lets you specify any one of the types given in the union, but it does not let you read either one one of those types out without first using a type guard to differentiate the type. That section says:

you can only access members that are guaranteed to be in all the constituents of a union type.

So, with your definition, you could satisfy TS by guarding like this:

const bar = (foo.members as string[]).includes("s") ? "does include" : "does not include";

Note that this can cause runtime errors if you guard to something that is not the actual underlying type.

Upvotes: 2

Related Questions