-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Array.prototype.filter doesn't require callback to return #19456
Comments
Although I'm a fan of strictness the loose signature is justified in this case, IMHO. PS: I feel a little uneasy adding 👎 on the proposals as it's ambiguous whether it's a vote cast on AMF or not. |
As I proposed in #20033: Maybe a new type (
A new type like function doStuff(callback: (arg: string) => TruthyFalsy): string[] {
let arr: string[] = ["item 1", "item 2", "item 3"];
let result: string[] = [];
for (let item of arr) {
// With TruthyFalsy, typescript can catch the bug on the next line:
if (callback(item) === true) { // Error: cannot compare type TruthyFalsy to type boolean
result.push(item);
}
}
return result;
} Basically, we don't allow people to compare
|
At a minimum, we should use |
A function isReady(): boolean {
return false;
}
if (isReady) { // compile error: type '() => boolean' is not allowed in an 'if' condition. Only types 'boolean' or 'TruthyFalsy' are allowed.
} The bug here, of course, is that we should have done Same for However, this could end up being overly restrictive. I often like to do As a workaround, we could allow |
I understood the @aj-r, you say it could be overly restrictive. I don’t understand. What am I missing in your examples?
If
Again, if |
@denis-sokolov That's an interesting idea that I hadn't considered - allow types to be implicitly cast to I still think we should still allow people to explicitly cast any value as function callback(value: any, index: number): TruthyFalsy {
if (typeof value === "string")
return true; // Should be allowed
if (typeof value === "object")
return false; // Should be allowed
return typeof value === "number" && value > 0;
} It would be really cool to see this in a future version of TypeScript. My only concern is that this type has some special cases that other types don't have, so it might be a lot of work to implement. |
I think it's really unfortunate that these library functions are defined by default to be sloppy instead of strict. In one of the really old suggestions for making the change from strict to sloppy: #5850 there was a suggestion to add your own override to make the function more sloppy by allowing any. However it seems using the same trick to add a new more strict override doesn't really work because the sloppy override still exists in lib.d.ts. The only solution I could come up with quickly was to add my own |
Our team ran into this today with Some Array methods allow for using generics like |
I dig a bit and found out in #5850 and subsequently in #7779 the signature of filter has been changed not to return a boolean, so that people could return a truthy value in the implementation of the filter.
While I undertand the convenience in terms of ease of use, this as far as I observed puts developers at risk of simple bugs like the following:
Notice the missing
return
statement means the function returnsundefined
, which translates tofalse
, which filters all the items out. This applies also in the case ofnoImplicitReturns
set to true, since the function return type isany
, thus it could be a void function for what the compiler knows.I believe TypeScript's job should be to put this kind of cases in check actually, so that things like truthy values (which sometimes aren't as obvious as we might think and introduce bugs we don't really understand) can be better taken care of.
One solution to make both parties happy would be to optionally support truthy values (maybe an extra compiler flag? Another
truthy
type to allow for more relaxed checking?) and reintroduce the original signature of filter.The text was updated successfully, but these errors were encountered: