Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dictionary type - why is undefined a possible entity value #930

Closed
GlynL opened this issue Mar 19, 2021 · 7 comments
Closed

Dictionary type - why is undefined a possible entity value #930

GlynL opened this issue Mar 19, 2021 · 7 comments

Comments

@GlynL
Copy link

GlynL commented Mar 19, 2021

export declare interface Dictionary<T> extends DictionaryNum<T> {
    [id: string]: T | undefined;
}

Getting the chance to use rtk for the first time, and using createEntityAdapter. Just coming across this and wondering why the possible value of an entity is undefined. The entity keys are created off the entity object so I can't imagine a scenario where it would be undefined. Not a big deal, but means accounting/coding for undefined every time you access an entity.

Thanks.

@markerikson
Copy link
Collaborator

Because if you were to access state.entities["abcd1234"], there's no guarantee there's an entity with that ID loaded.

So, rather than go with a TS type like Record<K, V> that says "we'll just assume that every field you access is valid", we opted to reflect reality. Agreed that it means doing a bit more bookkeeping, but consider it a safety precaution.

@GlynL
Copy link
Author

GlynL commented Mar 20, 2021

that's fair enough thanks for the reply. makes sense.

@GlynL GlynL closed this as completed Mar 20, 2021
@markerikson
Copy link
Collaborator

Sure.

The other answer is, "We ported createEntityAdapter from @ngrx/entity, that's the way they wrote it, and we just copied it" :)

@diegodlh
Copy link

diegodlh commented Aug 3, 2022

Just came up with the same question while experimenting with redux.

I'd like to add here that as a side effect of this there seem to be no way of iterating through all entities without checking whether they are undefined. I mean, following the example here, if one wants to do something for all entities using Object.values(state.entities).forEach(), one has to make sure that every entity is not undefined.

I feel this is inconsistent with the selectAll selector behavior, whose return type is T[] (instead of Array<T | undefined>).

Because if you were to access state.entities["abcd1234"], there's no guarantee there's an entity with that ID loaded.

Isn't this what tsconfig.json's noUncheckedIndexedAccess is for? I have it enabled so that indexing from an array does not assume that the return value will be defined:

const test: string[] = ["one", "two"];
const value = test[2];
// with noUncheckedIndexAccess, TypeScript understands that value may be undefined

Likewise, turning noUncheckedIndexedAccess on makes TypeScript understand that the value retrieved from a Record<string, string> object may be undefined.

@markerikson
Copy link
Collaborator

FWIW, the difference in behavior here in terms of both runtime and types is because selectAll iterates over the IDs array. So, we know that every lookup of state.entities[id] will have a valid result.

We could hypothetically change this, but at that point we're also sorta lying with the types. Then again, that's also what the built-in Record<K,V> type does.

@phryneas , thoughts ?

@phryneas
Copy link
Member

phryneas commented Aug 3, 2022

This type is a lot older than noUncheckedIndexedAccess, but was created with a similar intent. We could probably remove it in that context, but I'd wait for 2.0 for that.

@markerikson
Copy link
Collaborator

Oh yeah, it's totally a breaking change and would have to be part of a 2.0, I just wanted to see if you think that changing that would be a reasonable thing to do.

Okay, I'll add that to the 2.0 list, then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants