-
-
Notifications
You must be signed in to change notification settings - Fork 834
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
Typescript for models #3174
Typescript for models #3174
Conversation
* | ||
* @param data A resource object to merge into this model | ||
*/ | ||
pushData(data: ModelData | { relationships?: SaveRelationships }): this { |
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.
I did a lot of refactoring on this method to make it more understandable, less hacky, and more typesafe. This one needs a bit of extra review.
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.
Only reviewed about 65% of this so far :P
js/src/common/models/Discussion.ts
Outdated
title() { | ||
return Model.attribute<string>('title').call(this); | ||
} |
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.
wouldn't it be more friendly for attributes/relationships to write instead:
title() { | |
return Model.attribute<string>('title').call(this); | |
} | |
title = Model.attribute<string>('title'); |
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.
@SychO9 This breaks monkey patching I believe. Class properties are not in .prototype
and thus cannot be extended easily (if at all (?))
From Clark's PR
The difference between
Object.assign
/mixin
and the proposed solution is that the attributes are no longer part of the modelprototype
and as such cannot be easily overridden by extensions. However I don't think any extension ever attempted that and I'm not sure why the "mixin" style was used at all in the past.
More @ #2411 (comment)
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.
ah shame :(, the easier the code is the easier it is for new extension devs to get into it. But being able to monkey patch these is important as well.
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.
Personally, I don't think model attributes should really be monkey patched (that's a VERY unsafe approach to development), just that for now we need to maintain BC.
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.
It will create a difference between ext and core attributes, as we extend Models with prototype
, and once we switch over to class properties, those would be separate from the prototype. Don't think this would cause issues, but it might be confusing.
And yeah, think I'm for changing it in a breaking release as it's very ugly and repetitive.
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.
I'm hoping that by the time 2.0 rolls around, we will have proper JS extenders for this.
Co-authored-by: David Wheatley <hi@davwheat.dev>
Co-authored-by: David Wheatley <hi@davwheat.dev>
Co-authored-by: David Wheatley <hi@davwheat.dev>
Co-authored-by: David Wheatley <hi@davwheat.dev>
Co-authored-by: David Wheatley <hi@davwheat.dev>
Co-authored-by: David Wheatley <hi@davwheat.dev>
b8091c5
to
c543436
Compare
c543436
to
f26ad3e
Compare
Supercedes #2411
Part of flarum/framework#3310
Part of flarum/issue-archive#96
Changes proposed in this pull request:
Sorry in advance, this is a long one.
Convert Model.ts, Store.ts, and all models to TypeScript.
Reviewers should focus on:
As can be seen in the "Typecheck" GH action, this PR is sound from a type integrity perspective. There are, however a few concerns I have.
First and foremost, please take a look at the util types/interfaces I've added to
Store
andModel
, their naming, and whether everything that needs to be exported is actually being exported.Secondly, is there anything missing in the
Store
util types that should be there in order to comply with the JSON:API spec?Thirdly, the types for
computed
are very crude. Is there a better way to do this in a typesafe way?Fourthly, there currently isn't anything that enforces integrity of whether a model is saved being consistent with
exists
. One suggestion was to add aSaved extends boolean
generic param toModel
, and use conditional types to govern the types ofexists
anddata
. This makes things really messy though, as every subclass also needs to specify this, andthis
as a return type doesn't support swapping types when needed.Fithly, dealing with singular vs plural types with
Store.pushPayload
is a pain. SeeApplication.preloadedApiDocument
andStore.find
for an example. If anyone has ideas for a cleaner way to do this (or a way to constrain issues toStore.pushPayload
) that would be fantastic.Finally, and this is the biggest one, I've typed all model attributes as safely as I can:
| null
is added to all nullable fields, and| undefined
is added to all fields not included on the model'sBaseSerializer
. This is a bit clunky and overly broad, but it's safe. One idea I had to get around this is the concept ofSerializerProfiles
: this would be a generic argument to models representing which fields are present on a given serializer, and their types. It would then be used to generate all typings on all attributes. This sounds great in concept, but when trying to implement it, I had to use a lot of very ugly mapped and conditional types, as well as some very verbose generics and naming. As a result, I don't think it's worth going down that route.Necessity
Confirmed
composer test
).Required changes: