-
Notifications
You must be signed in to change notification settings - Fork 6
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
Allow entity types to infer what traits are known to be on them #36
Comments
I played around with this idea a bit, and managed to get a working prototype of this behavior: The problem with the solution in the linked StackBlitz is that the API for creating traits is a bit more complicated, and involves creating a unique symbol per trait explicitly: const PositionTrait = (() => {
const Id = Symbol();
return trait(Id, { x: 0, y: 0 });
})();
const VelocityTrait = (() => {
const Id = Symbol();
return trait(Id, { x: 0, y: 0 });
})(); As soon as the code inside the IIF is extracted into a common function, the returned unique symbols are no longer differentiated from each other, as seen in the "Approach 2" section in StackBlitz. function createTrait() {
const Id = Symbol();
return trait(Id, { x: 0, y: 0 });
}
const PositionTrait = createTrait();
const VelocityTrait = createTrait(); |
I was inspired by your StackBlitz so here is my attempt. First insight I got from your experiment is that in order for the entities to get a separate types for their trait generics, the generic has to be assigned to a field. That gets me further than I was before with a minimal reproduction here. But then going to make two identical schemas look unique required a manual key entry, as you said, no matter how I tried to break TS. And this makes sense, it is by design that uniqueness only comes from static code. Here is the minimal reproduction of that. So we have both confirmed it would require adding a key param to Also is the question of if we should. Your StackBlitz example made me think twice. A natural thing to do is spawn an entity with a few start traits which would then be embedded into its type. This could be passed by reference around maintaining its type and the assumption it has those starting traits. But then the same entity could be queried any place at any time and have those traits removed making the inferred traits now a liability depending the code. Since the traits on an entity are not actually static it is looking like this could end up exposing some nasty edge cases where the types are no longer reliable. Currently it always errs on the side of caution -- the types cannot know so you must tell TS if you know better with non-null assertion. It is annoying, but in the long run less prone to error. |
That is true. Unless entities become immutable, this will cause more issues that it's worth. |
The traits that are on an entity cannot be known statically, as they are dynamic by nature, but in some cases it is reasonable to infer this. For example, when an entity is queried with a Position trait and then that same entity has a
get
call for the position snapshot. We should be able to infer this is an entity that has a Position trait and not allow it to be possibly undefined.I have not found a type strategy that works for this yet but I am keen to explore these possibilities.
The test case:
The text was updated successfully, but these errors were encountered: