Happy Friday!
One of my Ember projects uses Firebase and ember-cloud-firestore-adapter
. For various reasons, the adapter requires the user to do some manual work when saving many-to-many relationships. I have a helper function that takes care of this work, for any type of Model:
// Original JS version
async setRelation(model, relationshipKey, newRelations) {
const previousRelations = model[relationshipKey].toArray();
const toAdd = difference(newRelations, previousRelations);
const toRemove = difference(previousRelations, newRelations);
for (const adding of toAdd) {
await this.addManyManyRelation(model, relationshipKey, adding);
}
for (const removing of toRemove) {
await this.removeManyManyRelation(model, relationshipKey, removing);
}
model[relationshipKey] = newRelations;
}
I’m trying to refactor this function using Typescript. Here’s where I am now:
// WIP refactor into TS
async setRelation<T extends Model, K extends string & keyof T>(model: T, relationshipKey: K, newRelations: []) {
let previousRelations: Model[] = (await model[relationshipKey]).toArray();
const toAdd = difference(newRelations, previousRelations);
const toRemove = difference(previousRelations, newRelations);
for (const adding of toAdd) {
await this.addManyManyRelation(model, relationshipKey, adding);
}
for (const removing of toRemove) {
await this.removeManyManyRelation(model, relationshipKey, removing);
}
model.set(relationshipKey, newRelations);
}
This all works fine in practice - the app behaves as intended - but I am getting an error about the use of .toArray()
:
Property 'toArray' does not exist on type 'Awaited<T[K]>'.glint:ts(2339)
I know I get a proxy when I do await model[relationshipKey]
and I know that I can call .toArray()
on that proxy, I just can’t track down what the proxy’s type is. I’ve tracked back through the Ember docs and can’t locate any information. Can anyone point me in the right direction?
I’m also aware that K
is currently too loose of a type. I really want K extends string & keyof T (but only if keyof is a relationship type)
. Is this possible? Is there a better way of typing K?