Skip to content

Enable strictNullChecks #1159

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

Merged
merged 1 commit into from
Aug 24, 2018
Merged

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Aug 22, 2018

Hmmm.

(BTW: This is the dumb version of this PR. There are likely asserts we could add to make sure that our assumptions are valid).

@schmidt-sebastian schmidt-sebastian force-pushed the mrschmdit-strictnullchecks branch from 92610ed to 7d9ac9b Compare August 22, 2018 23:10
@@ -1025,7 +1026,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
);
const query = await this.localStore.getQueryForTarget(targetId);
assert(!!query, `Query data for active target ${targetId} not found`);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could add an assertNotNull type guard that that would make the ! below unnecessary.

Something like:

assertNotNull<T>(value : T | null, explanation: string): arg is T {
  assert(!!value, explanation);
  return true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since these type guards only work in if-statements, this would change the calling site to:

  if (assertNotNull(query, `Query data for active target ${targetId} not found`)) {
        const queryData = await this.localStore.allocateQuery(query);
        await this.initializeViewAndComputeSnapshot(
            queryData,
            /*current=*/ false
        );
        this.remoteStore.listen(queryData);
      };

If we didn't have to put the explanation, then I would be all in favor. But with the explanation this looks a tad strange. If we do drop the explanation, we will never be able to trace these asserts back in minified code.

@@ -773,6 +776,10 @@ export class WebStorageSharedClientState implements SharedClientState {
return;
}

if (event.key === null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be ==? (We test event.newValue != null just below.)

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'm surprised that the linter didn't complain about event.newValue != null. We should not rely on type coercion, and I would guess that implicit coercion is almost always unintended. So rather than using == here, I changed the line below to !==. The type for LocalStorage are defined as "string | null", so they should never be undefined.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the issue is that == null is the one case where double-equal is actually useful because it handles undefined in a sane way. I don't actually know which we prefer, but ISTR this point being discussed.

@@ -26,7 +26,8 @@ import {
withTestDbs
} from '../util/helpers';

const Timestamp = firebase.firestore.Timestamp;
const Timestamp = firebase.firestore!.Timestamp;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is something wrong with our typings? Would our end users have to do something like this to enable strict null checks?

If not why do we need to do this?

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 asked Josh about this yesterday. The way our types are defined allows us to extend the firebase namespace after the fact without having to add all other product's APIs as well. Note that we don't ship generated typings, but only the hand-curated types in firestore-types and firebase-types.

Copy link
Contributor

@wilhuff wilhuff left a comment

Choose a reason for hiding this comment

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

LGTM

@wilhuff wilhuff assigned schmidt-sebastian and unassigned wilhuff Aug 24, 2018
@schmidt-sebastian schmidt-sebastian merged commit c08851c into master Aug 24, 2018
@schmidt-sebastian schmidt-sebastian deleted the mrschmdit-strictnullchecks branch September 5, 2018 18:22
@firebase firebase locked and limited conversation to collaborators Oct 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants