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

enable TS strict mode #10435

Closed
wants to merge 1 commit into from
Closed

enable TS strict mode #10435

wants to merge 1 commit into from

Conversation

paul-marechal
Copy link
Member

@paul-marechal paul-marechal commented Nov 19, 2021

What it does

Enable TS strict checks and fixes related problems in the code base.

I used a few strategies:

  • Any injected field is marked as not null with !
  • Unless there is a @optional() decorator in which case I mark the field as nullable with ?
  • Initialize boolean values with false because undefined is falsy (to conserve the current logic)
  • Initialize some fields as early as possible by slightly changing the logic
  • When not possible to initialize fields, I added checks at use time to fail early if something is undefined when it shouldn't

Then there's another special case with some classes like:

@injectable()
export class SomeOptions {
  readonly option1: string
  readonly option2: number
}

My guess is that this was more convenient than writing:

export const SomeOptions = Symbol('SomeOptions');
export interface SomeOptions {
  readonly option1: string
  readonly option2: number
}

The issue is that in the class version, the field are declared as not nullable, but they aren't initialized either. This means that doing new SomeOptions() will give back a bogus object. Furthermore those classes aren't ever instantiated: they're always used as a type and some regular JSON object is passed instead. To keep as much semantic, I fixed the issue by making both the class and its non nullable fields abstract.

Alternatively I could convert those classes into symbol+interface if we think it's a better idea.

Close #10417

How to test

Pure refactoring, everything should keep working like before.

Review checklist

Reminder for reviewers

@paul-marechal paul-marechal added the quality issues related to code and application quality label Nov 19, 2021
Copy link
Contributor

@colin-grant-work colin-grant-work left a comment

Choose a reason for hiding this comment

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

First round...

@@ -73,7 +73,7 @@ export class ExtensionPackageCollector {
if (RawExtensionPackage.is(pck)) {
const parent = this.parent;
const version = pck.version;
const transitive = !(name in this.root.dependencies!);
const transitive = !(name in this.root!.dependencies!);
Copy link
Contributor

Choose a reason for hiding this comment

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

How much do we gain if we mark it potentially undefined, and at the only mention that matters, simply assert that it isn't undefined?

Copy link
Member Author

@paul-marechal paul-marechal Nov 19, 2021

Choose a reason for hiding this comment

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

My guess is that if we had the strict checks enabled before, this method wouldn't have been implemented with this oddity in the first place. So not sure what to think about this code indeed. What I like right now is that it properly describes how root can be undefined but that this place expects it not to be.

Copy link
Member

Choose a reason for hiding this comment

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

In the rare case that this could become undefined in the future, I believe that having some sort of guard for that would be great. Something as simple as if (!this.root) { return; }

packages/core/src/browser/tree/tree.spec.ts Outdated Show resolved Hide resolved
packages/core/src/browser/widgets/widget.ts Show resolved Hide resolved

configure(conf: yargs.Argv): void {
conf.option('port', { alias: 'p', description: 'The port the backend server listens on.', type: 'number', default: DEFAULT_PORT });
conf.option('hostname', { alias: 'h', description: 'The allowed hostname for connections.', type: 'string', default: DEFAULT_HOST });
conf.option('ssl', { description: 'Use SSL (HTTPS), cert and certkey must also be set', type: 'boolean', default: DEFAULT_SSL });
conf.option('cert', { description: 'Path to SSL certificate.', type: 'string' });
conf.option('certkey', { description: 'Path to SSL certificate key.', type: 'string' });
conf.option(APP_PROJECT_PATH, { description: 'Sets the application project directory', default: this.appProjectPath() });
conf.option(APP_PROJECT_PATH, { description: 'Sets the application project directory' });
Copy link
Contributor

Choose a reason for hiding this comment

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

Why remove this default?

Copy link
Member Author

Choose a reason for hiding this comment

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

I had understood that BackendApplicationCliContribution.configure/setArguments wasn't called when this component was used, but turns out it might because the CLI is initialized in the generated app. Will revert this part now that I better understand how it works. I got confused.

@paul-marechal paul-marechal force-pushed the mp/ts-strict branch 3 times, most recently from fedd0a1 to 5323385 Compare November 19, 2021 18:14
@JonasHelming
Copy link
Contributor

@paul-marechal : Are you ready to trigger a re-review from colin?

@paul-marechal
Copy link
Member Author

@JonasHelming I will need to rebase first. I'd also like to have other opinions about this. I believe this is for the better despite the additional strictness, but I know some prefer it more lax...

@JonasHelming
Copy link
Contributor

@paul-marechal : I think we should not let this go stale, could you bring it up in the dev call again, please?

@paul-marechal
Copy link
Member Author

@JonasHelming if #10355 gets merged, there's even one more flag I'd like to turn on which would cause yet another big PR to align the code base with it: https://www.typescriptlang.org/tsconfig#noImplicitOverride

I'll bring it up at the next dev meeting.

@paul-marechal
Copy link
Member Author

So many conflicts... I'll close for now and come back to enable this flag in bits later.

@paul-marechal paul-marechal deleted the mp/ts-strict branch March 9, 2022 22:41
@paul-marechal paul-marechal restored the mp/ts-strict branch March 9, 2022 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
quality issues related to code and application quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

enable TypeScript strict checks
4 participants