-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
chore: added type information to core/field_dropdown.ts
#6550
Conversation
core/field_dropdown.ts
Outdated
if (isMenuGenerator(menuGenerator)) { | ||
if (Array.isArray(menuGenerator)) { | ||
validateOptions(menuGenerator); | ||
const trimmed = trimOptions(menuGenerator); |
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.
Before, trimOptions
was mutating the deep copied menuGenerator and, when no ImageProperties
labels were provided, setting a new value for menuGenerator_
. Assuming there's not an edge case I'm missing where the mutation is needed, this update shifts setting the value for menuGenerator_
to one point, and it should eliminate the need for a deep copy.
// is not assignable to parameter of type 'Node'. | ||
this.getTextElement().insertBefore( | ||
this.arrow_ as AnyDuringMigration, this.textContent_); | ||
this.getTextElement().insertBefore(this.arrow_, this.textContent_); |
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.
this.arrow_
apparently changed at some point since being given AnyDuringMigration
since it worked when I just removed AnyDuringMigration
.
Looks like there were a few commits from the |
Unfortunately this won't be a timely assumption, likely until our next release. It would be best to rebase onto develop. |
If |
Unfortunately no, that's just not how our workflow works. All PRs should go into develop as that is what we test with before merging a rollup of changes into master. Generally, master is equivalent with whatever code is currently on npm. Pushing something straight to master would break that assumption.
* We don't always merge master back into develop when doing a cherry-pick patch release, but my point is that it's not just during major releases. |
menuGenerator: MenuGenerator, opt_validator?: Function, | ||
opt_config?: FieldConfig); | ||
constructor(menuGenerator: Sentinel); | ||
constructor( |
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.
this one seems redundant with the first one. is there a reason it's not?
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.
For function overloading in TS, the final function's parameters need to support all of the previous functions' parameters. The final constructor supports MenuGenerator|Sentinel
since those are the cases that need to be handled in code within the constructor. It's also ultimately the limit of what can be provided, so a user could provide both a menuGenerator: Sentinel
and a validator.
The first two constructors here just guide what combinations should be provided. Without providing any parameters, it'll suggest providing a MenuGenerator
. If a Sentinel
is provided, it'll suggest not providing a validator or config. Since Sentinel is only for subclasses, it seems like most users won't want to provide it.
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 think this combination of constructors makes sense!
( | ||
// One or more strings will entirely vanish if we proceed. Abort. | ||
shortest <= prefixLength + suffixLength)) | ||
return {options: stringOptions}; |
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.
please add curly braces here; imo we should only skip them if the condition fits on one line, though I don't know if we have a written policy on this.
plus if you have braces, you can move the comment so it's not in the middle of the condition, and clang might give you something prettier.
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.
Will do! I think originally I had the return on line 714, though the formatter probably bumped it to a new line.
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.
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.
Could you still move the comment so that which part is the predicate is a bit easier to parse? I think either put it right above the if-statement, or right about the return statement.
core/field_dropdown.ts
Outdated
validateOptions(menuGenerator); | ||
const trimmed = trimOptions(menuGenerator); | ||
this.menuGenerator_ = trimmed.options; | ||
this.prefixField = trimmed.prefix || null; |
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.
if you have trimOptions
return null
instead of undefined
for a nonexistent prefix/suffix you could simplify this. or alternatively this.prefixField
could be changed to be optional instead of string|null
. I don't love the inconsistency between null and undefined here, though I recognize this problem is endemic to Blockly and is not a new issue here.
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.
Originally, I tried keeping the resulting values identical to the previous implementation in mind of a minor release. Since this will probably be included in a major release, though, I think it might be worth making prefixField
and suffixField
accept undefined instead of null. null
is in a weird spot where it's mostly symbolic now, perhaps conveying an explicit choice to provide a non-value rather than choosing to not provide a value.
I'll make the update in favor of undefined since it keeps the code more concise, though I can adjust either way.
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.
Actually, updating prefixField
and suffixField
would require updating the Field
parent class and impacted files so that'd be a pretty expansive change. Would it be fine to leave this as is for now? Ultimately I think those values probably should be just optional strings rather than string|null, though that's probably for a future PR.
1cd07df
to
a495529
Compare
I made most of the requested updates and cleaned up the branch to no longer include those commits from |
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! I wrote down a few nits, but they're all optional in my mind, so I'm going ahead and approving this =) Will merge Tuesday after making sure Maribeth is cool with it.
( | ||
// One or more strings will entirely vanish if we proceed. Abort. | ||
shortest <= prefixLength + suffixLength)) | ||
return {options: stringOptions}; |
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.
Could you still move the comment so that which part is the predicate is a bit easier to parse? I think either put it right above the if-statement, or right about the return statement.
// AnyDuringMigration because: Type '(this: FieldVariable) => any[][]' is | ||
// not assignable to type 'any[][] | ((this: FieldDropdown) => any[][])'. | ||
this.menuGenerator_ = FieldVariable.dropdownCreate as AnyDuringMigration; | ||
this.menuGenerator_ = FieldVariable.dropdownCreate as MenuGenerator; |
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.
Mmm this is kind of unfortunate (having to cast with as
), but I think this is the right thing to do here, b/c sadly expecting a FieldVariable
means it isn't actually a subtype :/
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.
Yeah, that was my thought as well. I explored a few different options, like updating dropdownCreate
to accept generics, though in the end this made the most sense.
Ideally this could be refactored such that this
isn't a parameter for the base function, though my goal was to avoid impacting the usage of each function.
menuGenerator: MenuGenerator, opt_validator?: Function, | ||
opt_config?: FieldConfig); | ||
constructor(menuGenerator: Sentinel); | ||
constructor( |
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 think this combination of constructors makes sense!
d26e782
to
aa007e3
Compare
Pulled in this week's |
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.
Thanks for making the changes and thanks to Beka for the additional review!
The basics
npm run format
andnpm run lint
The details
Resolves
Proposed Changes
Provided type information in place of
AnyDuringMigration
forcore/field_dropdown.ts
Behavior Before Change
Less type information.
Behavior After Change
More type information.
Reason for Changes
Cleaning up types that weren't included in the TS migration.
Test Coverage
N/A
Documentation
Yes - just the automatically generated documentation that utilizes the TS types.
Additional Information
I added comments to the file changes with anything of note. There are a couple of spots where the implementation of a few functions has been updated, though it shouldn't impact the functionality.