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

Update typings for getItem to account for the null case #858

Closed
wants to merge 20 commits into from

Conversation

Retsam
Copy link

@Retsam Retsam commented Oct 31, 2018

The typings don't currently account for the null case when doing getItem: from typescript's perspective, doing getItem will always return an item, while in practice it might be null. This allows for unsafe code like:

localforage.getItem<{foo: string}>("non-existent-key")
    .then(item => item.foo); // Compiles okay, but runtime errors, since `item` is null.

This updates the typings so that the return value reflects the null case. The new usage looks like:

localforage.getItem<{foo: string}>(key)
    .then(item => {
         if (!item) { /* Handle non-existence: default value, or throw error, whatever */}
         return item.foo;
    })

Or the TS ! operator can be used to say "trust me, it won't be null":

localforage.getItem<{foo: string}>('non-existent-key')
     // Same error as original case... but this time it's the consumer's fault for using the unsafe `!` operator.
     .then(item => item!.foo);

I also added a note about #42 . Since it's a JSDoc comment, it'll show up in intellisense:

screen shot 2018-10-31 at 3 55 46 pm

Technically, the typings could be written so that this function never returns undefined; however that depends on TS2.8. Anecdotally, that's probably fine, I think most TS users keep pretty up-to-date, but it seemed like a trivial reason to introduce a minimum version.

@thgreasi thgreasi self-requested a review November 2, 2018 07:39
Copy link
Member

@thgreasi thgreasi left a comment

Choose a reason for hiding this comment

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

LGTM but this sounds like a breaking change to me, since preexisting code will start complaining about the new unhandled null return value.
I will retarget this against the v2.0 dev branch.
Thanks 👍

PS: As for the current version, I guess that consumers will have to do a localforage.getItem<MyObject | null>('key');

@thgreasi thgreasi changed the base branch from master to v2.0-dev November 2, 2018 07:44
@thgreasi thgreasi changed the base branch from v2.0-dev to master November 2, 2018 07:44
@thgreasi
Copy link
Member

thgreasi commented Nov 2, 2018

Could we please rebase over the v2.0-dev branch and retarget this PR against it? If so, we can merge this sooner than later.

@Retsam Retsam changed the base branch from master to v2.0-dev January 4, 2019 19:23
@Retsam
Copy link
Author

Retsam commented Jan 4, 2019

@thgreasi Sorry it took me so long to get to this; I've repointed the PR at the dev branch.

@Retsam
Copy link
Author

Retsam commented Jan 4, 2019

FWIW, though I do think fixing typings can be considered a semver non-breaking change. At the least, I know several other packages seem to treat them that way, at least. To make an analogy, I've definitely had my linter find new lint errors after a minor version bump: yeah, it 'breaks' my compile step, but it doesn't break my runtime code.

Personally, as a consumer of types, I'd rather get notified of possible runtime errors sooner, so I'd probably put it as a minor version (not a patch), but if you want it in the v2 branch, that's fine too.

@thgreasi
Copy link
Member

@Retsam you are right, I just faced this typing issue while writting a new custom driver in TS. Let's get this in v1.8, so that custom driver plugins are able to have a clear migration step.

@thgreasi thgreasi changed the base branch from v2.0-dev to master January 12, 2019 10:19
@thgreasi
Copy link
Member

Please change the base of your branch to be the current master, or if you prefer it I can try cherrypicking the commit, but in that case I'm not sure whether GH will consider the PR merged or not.

@Etheryte
Copy link

Etheryte commented Nov 2, 2019

LGTM but this sounds like a breaking change to me, since preexisting code will start complaining about the new unhandled null return value.

A better way to look at this would be that preexisting code will now correctly warn about unhandled cases at build time instead of giving a runtime error. Having your build break when you update dependencies is a much better option than having your code break at runtime.

As a consumer, it would be nice to get this merged asap and be assured all the types are correct everywhere. Currently we need to <T | null> every getter and be doubly careful for human error.

@tofumatt
Copy link
Member

tofumatt commented Nov 2, 2019

I think @Etheryte's point makes sense; this is sort of a fix more than a breaking change. It will result in people having to update their code, but it will fail as expected, so it's really more like a bugfix. 🤷‍♂

@thgreasi
Copy link
Member

thgreasi commented Aug 1, 2020

Resolved in v1.9.0 by #980

@thgreasi thgreasi closed this Aug 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants