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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make anyArray.filter(Boolean) return any[], not unknown[] #31515

Merged
merged 5 commits into from May 22, 2019

Conversation

sandersn
Copy link
Member

@sandersn sandersn commented May 21, 2019

Allows anys.filter(Boolean) to once again return any[], not unknown[].

Fixes #31189

Doesn't break any of our test suite, but I'm running it on user tests and I need to request a DT and RWC run.

Edit: I've found three solutions:

  1. Change the type parameter on the boolean factory function that is also a type guard from T to T extends any. This will break if Reinterpret a type parameter constrained to any as an upper bound constraint聽#29571 goes in [1].
  2. Change the boolean factory function to not be a type guard. This means that you can't get the truthy part of a string | undefined union by calling Boolean (but you can define your own type guard of course).
  3. Change the first overload of filter to
<S extends T>(f: (value: T) => value is S): unknown extends T ? any[] : S[]

I like (2) the best since you can always write your own type guard and I have never seen if (Boolean(x)) in JS or TS before, and we haven't shipped it so nobody relies on it yet. (3) is a bad example in a 馃 馃懡 馃 "why not overloads + conditional types" way.

I'll switch to (2) and make sure the test results look good.

[1] I'm not sure that #29571 is a good change, but it is a safer change. My intent with T extends any is basically "disable type checking for this type parameter", but I think it's also common to use it to mean T extends unknown.

Allows anys.filter(Boolean) to once again return any[], not unknown[].
@sandersn
Copy link
Member Author

I'm also going to keep looking at the original failure to see whether there's a bug in assignability that causes.

@sandersn
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 21, 2019

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at ccf38f6. You can monitor the build here. It should now contribute to this PR's status checks.

@sandersn
Copy link
Member Author

@typescript-bot run rwc

@sandersn
Copy link
Member Author

@typescript-bot test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 21, 2019

Heya @sandersn, I've started to run the extended test suite on this PR at f80dd7e. You can monitor the build here. It should now contribute to this PR's status checks.

declare var Bullean: BulleanConstructor;
declare let anys: Ari<any>;
var xs: Ari<any>;
var xs = anys.filter(Bullean)
Copy link
Member Author

Choose a reason for hiding this comment

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

this should fail since I didn't fix the small repro example.

~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'xs' must be of type 'Ari<any>', but here has type 'Ari<unknown>'.

declare let realanys: any[];
Copy link
Member Author

Choose a reason for hiding this comment

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

this should pass, and does, after the workaround.

@sandersn
Copy link
Member Author

RWC, DT and user tests are all clean.

@sandersn
Copy link
Member Author

Hold the phone. I changed ReadonlyArray.filter by mistake, not Array.filter. Both need to be changed. I'll re-run tests and re-report how much breaks.

I want to test how well this works.
@sandersn
Copy link
Member Author

Well, that didn't work.

I'm changing the Boolean factory function for now. The user tests show no changes except fixes for the errors introduced by the original PR.

@sandersn
Copy link
Member Author

@typescript-bot test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 21, 2019

Heya @sandersn, I've started to run the extended test suite on this PR at e118188. You can monitor the build here. It should now contribute to this PR's status checks.

@sandersn
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 21, 2019

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at e118188. You can monitor the build here. It should now contribute to this PR's status checks.

@sandersn
Copy link
Member Author

@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 21, 2019

Heya @sandersn, I've started to run the community code test suite on this PR at e118188. You can monitor the build here. It should now contribute to this PR's status checks.

src/lib/es5.d.ts Outdated
@@ -513,7 +513,7 @@ interface Boolean {

interface BooleanConstructor {
new(value?: any): Boolean;
<T>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
<T extends any>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
Copy link
Member

Choose a reason for hiding this comment

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

#29571 will 100% break this (and we only held off merging it because we got spooked with the number of breaks already in 3.5 IIRC), since this is a terrible hack that makes T "look like any" even though it's a type parameter and extends any should be identical to extends unknown or simply no constraint.

@RyanCavanaugh
Copy link
Member

I'm proposing we just revert #29955. The cure here seems worse than the disease we were trying to address

@sandersn sandersn changed the title Add this-parameter workaround to Array.filter Make anyArray.filter(Boolean) return any[], not unknown[] May 22, 2019
@sandersn
Copy link
Member Author

@RyanCavanaugh I agree. I didn't even notice that the Boolean factory was not a type guard until 3 weeks ago. I switched it back to boolean and wrote up our options in the description.

@sandersn
Copy link
Member Author

sandersn commented May 22, 2019

@typescript-bot run dt
@typescript-bot test this

User tests look good on my local machine; the anys.filter(Boolean) errors are gone.

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 22, 2019

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at ab9d935. You can monitor the build here. It should now contribute to this PR's status checks.

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 22, 2019

Heya @sandersn, I've started to run the extended test suite on this PR at ab9d935. You can monitor the build here. It should now contribute to this PR's status checks.

@sandersn sandersn merged commit b36c8a0 into master May 22, 2019
@@ -513,7 +513,7 @@ interface Boolean {

interface BooleanConstructor {
new(value?: any): Boolean;
<T extends any>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
<T>(value?: T): boolean;
Copy link

Choose a reason for hiding this comment

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

but what about

(someArray as SomeType[]).map(some => {
    if (!some.test) return;  // after this line the result will be (SomeType || undefined)[] 
    return some;
}).filter(Boolean); // here undefined was filtered with Exclude in definitions

it breaks #29955 :{

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.

Inference from multiple signatures produces unknown instead of any
5 participants