-
Notifications
You must be signed in to change notification settings - Fork 30.4k
[@types/lodash] _.filter types break when combined with _.get #21485
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
Comments
Tagging some authors here: |
TS version? Compiler settings? |
TS version 2.5.3 and 2.6.1 and I'm not sure the compiler settings are relevant in this case?
|
It thinks that |
Well that's not good.. I can't figure out where it would be picking up |
It's a problem of the |
This is intended. The callback for const obj = {
hi: false,
there: true
};
const merp: string[] = _.filter(_.keys(obj as Array<keyof typeof obj>), (x) => { // or `Array<"hi" | "there">
return _.get(obj, x);
}); or alternatively: const obj: { [key:string]: boolean } = {
hi: false,
there: true
};
const merp: string[] = _.filter(_.keys(obj), (x) => {
return _.get(obj, x);
}); However this example seems a bit contrived, and I wonder why you don't just use If your |
The docs for Unfortunately, this example may seem contrived since it is a minimal and reproducible example and not my full production code. I suppose to be a bit more true to how it is being used in production you could imagine this situation:
Anyways, this was working a few days ago as expected because |
Actually, with both of your help it is more clear to me what is happening; so a much more minimal example would be:
again, maybe slightly contrived, but it's not hard to imagine a place where filter could be used to return a non-boolean result. |
There was a lengthy discussion here about whether callbacks should return That said, the Mentioning @Andy-MS because he was involved in this discussion. |
Ah, thanks for the link! I missed this as I was skimming that PR. Still not used to github folding some of the comments in "outdated" tags, so I keep missing some of these discussions. This is an interesting discussion that I hadn't considered: Typescript seems unique among typed languages in that it even has the concept of "truthy" and "falsy". My immediate reaction here is that leveraging truthy/falsy is an incredibly common pattern in javascript that Typescript may not be capable of supporting. I'd almost be interested in defining two types:
This, however, would not be possible right now as there is no way of distinguishing The flipside here is that enforcing a boolean is slightly divergent from the lodash docs, which meant finding the source of the error for me was not immediately obvious. Additionally, this is code that has been building/running successfully for months that suddenly broke after a patch version bump in the npm repository. TL;DR, after my wordy "thinking aloud": I am indifferent to whether or not the predicate should return a Anyways, thanks for the discussion. This makes a lot more sense to me, now seeing the reason behind the change. |
See also microsoft/TypeScript#20033 |
(Full disclosure: I'm a teammate of @andnp , looking at the same error in the same codebase and wanted to add my thoughts: I'm not trying to "sock-puppet" here) I appreciate the efforts to improve lodash typings, but I disagree with the changes to On the first level, I don't really agree with the idea of changing IMO, the typings for a library should reflect the conventions and the documented behavior of the library as much as possible, and generally shouldn't add opinion-based restrictions that don't exist in the original library. For one thing, it makes migration to TS harder when there are these sort of restrictions in TS that don't exist in the JS versions. Yeah, individually it's an easy fix (add !!), but it can become burdensome quickly when migrating existing code: especially if there's a lot of these opinionated restrictions. It can quickly get into a "death by a thousand cuts" sort of scenario. On the second level, (i.e. ignoring the previous objections) I don't think the end result of the current implementation of that restriction is good. If we want to restrict filter callbacks to only return booleans, then When debugging this it wasn't even immediately obvious that Plus, it just ends up being inconsistent: it's unintuitive that And, additionally, this breaks if the function passed to And on the third level, as andyp said, it's painful that this happened in a patch version. I'm not sure if it's just an endemic problem within all of DefinitelyTyped, but breaking type changes on patch version isn't fun. I don't know that much about the DefinitelyTyped repository's mechanics, but if there's a way to avoid that in the future, it'd be appreciated. So, personally, I'd really like to see some changes to 1 It really is an ugly type, after doing
|
@Retsam what would you think about an option to allow passing of potentially-truthy-potentially-falsy values to |
@Andy-MS That'd definitely address my main objection to the change (i.e. the "first level" objection from my previous post), on principle. It would probably be the best of both worlds to allow the typings to be stricter and allow users to opt-out of that strictness, if they prefer. But I'm not sure I'd want lodash to be strict in the interim while that Typescript feature doesn't exist, |
I'm inclined to agree. We could make these callbacks return lodash's
`NotVoid ` type, which is just `{} | null | undefined` until typescript has
a looser version of a Boolean return type. That's better than `any` because
we at least force people to return a value in the callbacks.
On Nov 21, 2017 5:19 PM, "Retsam" <[email protected]> wrote:
@Andy-MS <https://github.com/andy-ms> That'd definitely address my main
objection to the change (i.e. the "first level" objection from my previous
post), on principle. It would probably be the best of both worlds to allow
the typings to be stricter and allow users to opt-out of that strictness,
if they prefer.
But I'm not sure I'd want lodash to be strict in the interim while that
Typescript feature doesn't exist,
and in any case, I still think the "ergonomics" of the current
implementation aren't great. I'm not sure the proposed Typescript option
would even have any affect on the current state of _.filter, since it's not
failing because boolean isn't any, it's failing because _.filter is
spitting out junk types.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#21485 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGpeswEgMxob6sCRwZF6h9hIdAQq80R4ks5s40xigaJpZM4Qb90F>
.
|
I'm finding the same issue with _.reject coupled with _.isUndefined, wondering if it is related: const array = ['some', 'value', undefined, 'another'];
_(array).reject(_.isUndefined).value(); // any[]
_(array).reject(a => _.isUndefined(a)).value(); // string[] I can type the reject function directly, which types the return as expected, but I feel like there should be a way to infer this typing, as in the second example above: _(array).reject<string>(_.isUndefined).value(); // string[] TS 2.9.2 with default compiler options. |
Hi thread, we're moving DefinitelyTyped to use GitHub Discussions for conversations the To help with the transition, we're closing all issues which haven't had activity in the last 6 months, which includes this issue. If you think closing this issue is a mistake, please pop into the TypeScript Community Discord and mention the issue in the |
I think that we are somehow getting into the wrong function overload for
_.filter
here.is a simplified version of what we are doing.
also breaks in the same way (although I think it actually prefers yet another overload).
In the first example the filter function is inferred to be:
in the second:
It seems this broke after #20795 went in (which has some changes to the
_.filter
types).For now we can fix it with:
The text was updated successfully, but these errors were encountered: