-
Notifications
You must be signed in to change notification settings - Fork 406
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
feat(store): implements StateToken<T> #1436
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(edited)
That is great, how soon can we see that released? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really well done with this PR. That TS typing code looks crazy.
I am so excited about the type safety that this will bring.
I still believe that we should not have this service locator cache for state tokens.
I will have a look at this branch and try to see if I can remove that part and still have everything working.
@markwhitfeld I added tests, the main thing is do not delete them, and help if you can |
It requires at least 1 unique public method in order for the type inference to work correctly
I can't figure out why this is failing in CI. It is all happy on my machine. |
Ok, I think I fixed it. I had to expose a fake method that returned the type T so that TS did not ignore the generic parameter. |
5f1e3f4
to
18bdb74
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good so far.
We still need the following:
- Add to docs
- Decide if the name is to stay
StateToken
or change toStateKey
. See 🚀[PROPOSAL]: State Class Token #1391 for discussion. - Does this still allow for not exposing the model type? See below.
From the proposal #1391:
export const TODO_STATE_TOKEN = new StateToken<TodoStateModel>('todos');
// or if we do not want to expose type information
export const TODO_STATE_TOKEN = new StateToken('todos');
I know that we have a create
function here instead of using the new
.
Let's say that the user wants to provide the token but does not want to expose the internals of the Model type. Can we do that with the current implementation? Would you just specify any
or unknown
?
Also, what are the advantages of the create
function over the new
?
It makes no sense not to show the type of model, since this will not be useful, but only add an extra entity What are the advantages over const TODOS_TOKEN = StateToken.create<any>('todos'); // any model
@State({
name: TODOS_TOKEN,
default: {}
})
class TodoState {} const TODOS_TOKEN = 'todos'; // string :)
@State({
name: TODOS_TOKEN,
default: {}
})
class TodoState {}
You can StateToken.create<unknown>('myToken'); but use
Single entry point to create a token. We can manually control the creation constructor. Since the constructor is private, we can change the signature without critical changes next releases. |
In some cases users would want to treat the data structure internal to their states as private and not expose it. This is along the idea of encapsulating private information. This would force the only access to be through the selectors. This is a reasonable practice.
Currently, this throws an error given the current implementation (through the I agree with your reasoning for the |
You can always use StateToken.create<any>('token'); But I'm sure it is not necessary in 90 percent of applications.
Yes, it was specifically designed to motivate the user to specify the data type StateToken.create<any>('myToken'); // or StateToken.create<MyModel>('myToken'); It is necessary to indicate in the documentation that users try to indicate the data type, so that they understand that this improves typing |
@arturovt please review again |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great!
Let's just wait for a bit more feedback on the proposal before we merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for that grammatic requests 😝
I also asked to remove public
modifiers because:
we have spoken before that the convention in the project is not to include the public keyword on method declarations.
(c) @markwhitfeld
There are more comments. Click "show hidden" or something like that... Not sure why github doesn't show all... |
@arturovt fixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Ok, I think we have to hold it a little bit... As Mark said maybe some users may have to leave something in the issue...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturovt Could you confirm that you are happy with the docs?
@splincode Do you think you could add some details to the release announcement post in this PR? |
@markwhitfeld yes, we need |
@splincode I merged the announcement PR so that we can add those details to the article as commit in this PR. |
Could you update announcement? |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: #1391
What is the new behavior?
Enhanced Type Safety State Token
Enhanced Type Safety State Decorator
Enhanced Type Safety Selector Decorator
Enhanced Type Safety Select Decorator
Easy extensibility, scaling due to easy adapter
StateToken.inject(MyState); // Extensible API
StateToken.inject('myState'); // Extensible API
Does this PR introduce a breaking change?
@markwhitfeld @arturovt Unfortunately, I can’t implement Angular 5 support + TS 2.7
With only minimal support TS 2.8