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

refactor(blocks): Migrate blocks/math.js to TypeScript #6900

Merged
merged 7 commits into from
Mar 17, 2023

Conversation

cpcallen
Copy link
Contributor

The basics

  • I branched from develop
  • My pull request is against develop
  • My code follows the style guide
  • I ran npm run format and npm run lint

The details

Resolves

Part of #6828.

Additional Information

The types are not completely finalised, in particular because BlockDefinition is defined as AnyDuringMigration, and so it has been necessary in a few places to use .! and/or as AnyDuringMigration. Hopefully it will be possible to address these in a future PR.

@cpcallen cpcallen added component: library blocks PR: chore General chores (dependencies, typos, etc) labels Mar 16, 2023
@cpcallen cpcallen requested a review from a team as a code owner March 16, 2023 17:53
@cpcallen cpcallen requested a review from gonfunko March 16, 2023 17:53
@github-actions github-actions bot removed the PR: chore General chores (dependencies, typos, etc) label Mar 16, 2023
blocks/math.ts Outdated Show resolved Hide resolved
blocks/math.ts Show resolved Hide resolved
blocks/math.ts Outdated
this.updateType_(newOp);
}.bind(this));
const LIST_MODES_MUTATOR_EXTENSION = function(this: Block) {
this.getField('OP')!.setValidator(function(this: Field, newOp: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the validator be converted to an arrow function to avoid having to explicitly bind this/generally modernize it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, because the validator makes use of this, and if I understand correctly an arrow expression here would have this irrevocably bound to LIST_MODES_MUTATOR_EXTENSION, which is not what we want.

(If only block definitions were classes, and these could just be ordinary methods!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(No, now that I think more carefully I think that's wrong: this would be undefined—still wrong.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I look at this bit of code the weirder it is. I think I will rewrite it—but in a future PR. For now just try to preserve existing behaviour exactly.

Define types to represent the union of Block and each of the
*_MIXINs, and use these types for the type of this in mixin
methods.
Make sure validator functions explicitly return undefined.
Field.prototype.setValidator takes a FieldValidator<T>, which
must be a non-void function.  I'm not sure why tsc was not
objecting to the void implementation here, but it does in
other very similar situations so for consistency explicitly
return undefined to signal the value should be used unchanged.

Also undo previous change of !. to ?.: I think it wisest to
try to preserve the existing behaviour as exactly as possible
for now, and make behaviour changes (i.e., ones that affect
the generated code) separately.
@cpcallen
Copy link
Contributor Author

I learned a bunch about how to more cleanly fix some type errors while working on lists.ts, and have applied those changes via two additional commits on this PR.

It turns out that the previous types for these were completely
wrong, for two reasons:

- They should be intersection types (which have the union of the
  properties), not union types (which have the interseciton of the
  properties).
- The *_MIXIN types were already declared as having type
  BlockDefinition, which is ultimately an alias for any.

TypeScript doesn't like (some) kinds of circularly defined types,
so fixing the above necessitates declaring a few auxiliary types
just to make the type checker happy - but the end result is
excellent and caught an actual type error in the code.
@cpcallen
Copy link
Contributor Author

One more update:

It turns out that the previous types for the mixins were completely wrong, for two reasons:

  • They should be intersection types (which have the union of the properties), not union types (which have the interseciton of the properties).
  • The *_MIXIN objects were already declared as having type BlockDefinition, which is ultimately an alias for any.

TypeScript doesn't like (some) kinds of circularly defined types, so fixing the above necessitates declaring a few auxiliary types just to make the type checker happy - but the end result is excellent and caught an actual type error in the code.

blocks/math.ts Show resolved Hide resolved
blocks/math.ts Outdated Show resolved Hide resolved
blocks/math.ts Outdated Show resolved Hide resolved
@cpcallen
Copy link
Contributor Author

So, I forgot to push commit 8591f44 before asking you to look again. Sorry. Do feel free to have a look at again, because the declaration of the types of the mixins is much more correct but also much less pleasant.

@cpcallen cpcallen merged commit bb9f318 into google:develop Mar 17, 2023
@cpcallen cpcallen deleted the fix/6828/blocks/math branch June 21, 2023 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants