Changing UpdateData to expand support for types with index signatures. by MarkDuckworth · Pull Request #7318 · firebase/firebase-js-sdk (original) (raw)

This change relaxes UpdateData<T>, so that dot notation can be used to update types T where T contains an index signature. An example type T that this affects:

interface MyV10ServerType {
  indexed: {
    [name: string]: {
      booleanProperty: boolean,
      numberProperty: number
    }
  }
};

Without this change, dot notation can not be used to update field 'indexed.foo.booleanProperty'.

const update: UpdateData<MyV10ServerType> = {
  'indexed.foo.booleanProperty': true <-- TS2322: Type 'true' is not assignable to type '{ booleanProperty?: boolean | FieldValue | undefined; numberProperty?: number | FieldValue | undefined; } | FieldValue | undefined'.
}

updateDoc<MyV10ServerType>(docRef, update);

With this change, the following code is now possible:

const update: UpdateData<MyV10ServerType> = {
  'indexed.foo.booleanProperty': true
}

updateDoc<MyV10ServerType>(docRef, update);

The downside of this change is that we lose type safety and auto-complete for these types. For example we can do the following:

const update: UpdateData<MyV10ServerType> = {
  'indexed.foo': 'foo is not a string, it should be an object, but we can't enforce that...'
}

However, type safety and auto-complete are still in place if doing full object replacement:

// This is an example of update data that does a full object replacement
const update: UpdateData<MyV10ServerType> = {
  indexed: {
    foo: {
      booleanProperty: true,
      numberProperty: 1
    }
  }
}

And, we should note that type safety and auto complete are still in place for nested types when index signature is not involved.

interface NestedObject {
  indexed: {
    // see, no index signature on this line
    foo: {
      booleanProperty: boolean,
      numberProperty: number
    }
  }
};

const update: UpdateData<NestedObject> = {
  'indexed.foo.booleanProperty': true // we have type safety and auto-complete for this
}

Fixes #6105

Reviewers should understand that the unit tests in lite-api/types.test.ts are all new. These tests are introduced in a different pull request (7319) and are intended to ensure that UpdateData does not regress in unexpected ways with the fix in this PR.