Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b36c8a0

Browse filesBrowse files
authored
Make anyArray.filter(Boolean) return any[], not unknown[] (microsoft#31515)
* Add this-parameter workaround to Array.filter Allows anys.filter(Boolean) to once again return any[], not unknown[]. * Add any constraint to Boolean factory function I want to test how well this works. * Remove Boolean factory type guard * Remove typeGuardBoolean test
1 parent 1e7a77c commit b36c8a0
Copy full SHA for b36c8a0

9 files changed

+264-124Lines changed: 264 additions & 124 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/lib/es5.d.ts‎

Copy file name to clipboardExpand all lines: src/lib/es5.d.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ interface Boolean {
513513

514514
interface BooleanConstructor {
515515
new(value?: any): Boolean;
516-
<T>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
516+
<T>(value?: T): boolean;
517517
readonly prototype: Boolean;
518518
}
519519

Collapse file
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [booleanFilterAnyArray.ts]
2+
interface Bullean { }
3+
interface BulleanConstructor {
4+
new(v1?: any): Bullean;
5+
<T>(v2?: T): v2 is T;
6+
}
7+
8+
interface Ari<T> {
9+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
10+
filter(cb2: (value: T) => unknown): Ari<T>;
11+
}
12+
declare var Bullean: BulleanConstructor;
13+
declare let anys: Ari<any>;
14+
var xs: Ari<any>;
15+
var xs = anys.filter(Bullean)
16+
17+
declare let realanys: any[];
18+
var ys: any[];
19+
var ys = realanys.filter(Boolean)
20+
21+
var foo = [{ name: 'x' }]
22+
var foor: Array<{name: string}>
23+
var foor = foo.filter(x => x.name)
24+
var foos: Array<boolean>
25+
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
26+
27+
28+
//// [booleanFilterAnyArray.js]
29+
var xs;
30+
var xs = anys.filter(Bullean);
31+
var ys;
32+
var ys = realanys.filter(Boolean);
33+
var foo = [{ name: 'x' }];
34+
var foor;
35+
var foor = foo.filter(function (x) { return x.name; });
36+
var foos;
37+
var foos = [true, true, false, null].filter(function (thing) { return thing !== null; });
Collapse file
+108Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
=== tests/cases/compiler/booleanFilterAnyArray.ts ===
2+
interface Bullean { }
3+
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
4+
5+
interface BulleanConstructor {
6+
>BulleanConstructor : Symbol(BulleanConstructor, Decl(booleanFilterAnyArray.ts, 0, 21))
7+
8+
new(v1?: any): Bullean;
9+
>v1 : Symbol(v1, Decl(booleanFilterAnyArray.ts, 2, 8))
10+
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
11+
12+
<T>(v2?: T): v2 is T;
13+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
14+
>v2 : Symbol(v2, Decl(booleanFilterAnyArray.ts, 3, 8))
15+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
16+
>v2 : Symbol(v2, Decl(booleanFilterAnyArray.ts, 3, 8))
17+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
18+
}
19+
20+
interface Ari<T> {
21+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
22+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
23+
24+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
25+
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
26+
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
27+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
28+
>cb1 : Symbol(cb1, Decl(booleanFilterAnyArray.ts, 7, 24))
29+
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
30+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
31+
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
32+
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
33+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
34+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
35+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
36+
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
37+
38+
filter(cb2: (value: T) => unknown): Ari<T>;
39+
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
40+
>cb2 : Symbol(cb2, Decl(booleanFilterAnyArray.ts, 8, 11))
41+
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 8, 17))
42+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
43+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
44+
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
45+
}
46+
declare var Bullean: BulleanConstructor;
47+
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
48+
>BulleanConstructor : Symbol(BulleanConstructor, Decl(booleanFilterAnyArray.ts, 0, 21))
49+
50+
declare let anys: Ari<any>;
51+
>anys : Symbol(anys, Decl(booleanFilterAnyArray.ts, 11, 11))
52+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
53+
54+
var xs: Ari<any>;
55+
>xs : Symbol(xs, Decl(booleanFilterAnyArray.ts, 12, 3), Decl(booleanFilterAnyArray.ts, 13, 3))
56+
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
57+
58+
var xs = anys.filter(Bullean)
59+
>xs : Symbol(xs, Decl(booleanFilterAnyArray.ts, 12, 3), Decl(booleanFilterAnyArray.ts, 13, 3))
60+
>anys.filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
61+
>anys : Symbol(anys, Decl(booleanFilterAnyArray.ts, 11, 11))
62+
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
63+
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
64+
65+
declare let realanys: any[];
66+
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
67+
68+
var ys: any[];
69+
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
70+
71+
var ys = realanys.filter(Boolean)
72+
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
73+
>realanys.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
74+
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
75+
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
76+
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
77+
78+
var foo = [{ name: 'x' }]
79+
>foo : Symbol(foo, Decl(booleanFilterAnyArray.ts, 19, 3))
80+
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
81+
82+
var foor: Array<{name: string}>
83+
>foor : Symbol(foor, Decl(booleanFilterAnyArray.ts, 20, 3), Decl(booleanFilterAnyArray.ts, 21, 3))
84+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
85+
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 20, 17))
86+
87+
var foor = foo.filter(x => x.name)
88+
>foor : Symbol(foor, Decl(booleanFilterAnyArray.ts, 20, 3), Decl(booleanFilterAnyArray.ts, 21, 3))
89+
>foo.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
90+
>foo : Symbol(foo, Decl(booleanFilterAnyArray.ts, 19, 3))
91+
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
92+
>x : Symbol(x, Decl(booleanFilterAnyArray.ts, 21, 22))
93+
>x.name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
94+
>x : Symbol(x, Decl(booleanFilterAnyArray.ts, 21, 22))
95+
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
96+
97+
var foos: Array<boolean>
98+
>foos : Symbol(foos, Decl(booleanFilterAnyArray.ts, 22, 3), Decl(booleanFilterAnyArray.ts, 23, 3))
99+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
100+
101+
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
102+
>foos : Symbol(foos, Decl(booleanFilterAnyArray.ts, 22, 3), Decl(booleanFilterAnyArray.ts, 23, 3))
103+
>[true, true, false, null].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
104+
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
105+
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
106+
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
107+
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
108+
Collapse file
+94Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
=== tests/cases/compiler/booleanFilterAnyArray.ts ===
2+
interface Bullean { }
3+
interface BulleanConstructor {
4+
new(v1?: any): Bullean;
5+
>v1 : any
6+
7+
<T>(v2?: T): v2 is T;
8+
>v2 : T
9+
}
10+
11+
interface Ari<T> {
12+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
13+
>filter : { <S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>; (cb2: (value: T) => unknown): Ari<T>; }
14+
>cb1 : (value: T) => value is S
15+
>value : T
16+
17+
filter(cb2: (value: T) => unknown): Ari<T>;
18+
>filter : { <S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>; (cb2: (value: T) => unknown): Ari<T>; }
19+
>cb2 : (value: T) => unknown
20+
>value : T
21+
}
22+
declare var Bullean: BulleanConstructor;
23+
>Bullean : BulleanConstructor
24+
25+
declare let anys: Ari<any>;
26+
>anys : Ari<any>
27+
28+
var xs: Ari<any>;
29+
>xs : Ari<any>
30+
31+
var xs = anys.filter(Bullean)
32+
>xs : Ari<any>
33+
>anys.filter(Bullean) : Ari<any>
34+
>anys.filter : { <S extends any>(cb1: (value: any) => value is S): Ari<any>; (cb2: (value: any) => unknown): Ari<any>; }
35+
>anys : Ari<any>
36+
>filter : { <S extends any>(cb1: (value: any) => value is S): Ari<any>; (cb2: (value: any) => unknown): Ari<any>; }
37+
>Bullean : BulleanConstructor
38+
39+
declare let realanys: any[];
40+
>realanys : any[]
41+
42+
var ys: any[];
43+
>ys : any[]
44+
45+
var ys = realanys.filter(Boolean)
46+
>ys : any[]
47+
>realanys.filter(Boolean) : any[]
48+
>realanys.filter : { <S extends any>(callbackfn: (value: any, index: number, array: any[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: any, index: number, array: any[]) => unknown, thisArg?: any): any[]; }
49+
>realanys : any[]
50+
>filter : { <S extends any>(callbackfn: (value: any, index: number, array: any[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: any, index: number, array: any[]) => unknown, thisArg?: any): any[]; }
51+
>Boolean : BooleanConstructor
52+
53+
var foo = [{ name: 'x' }]
54+
>foo : { name: string; }[]
55+
>[{ name: 'x' }] : { name: string; }[]
56+
>{ name: 'x' } : { name: string; }
57+
>name : string
58+
>'x' : "x"
59+
60+
var foor: Array<{name: string}>
61+
>foor : { name: string; }[]
62+
>name : string
63+
64+
var foor = foo.filter(x => x.name)
65+
>foor : { name: string; }[]
66+
>foo.filter(x => x.name) : { name: string; }[]
67+
>foo.filter : { <S extends { name: string; }>(callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => unknown, thisArg?: any): { name: string; }[]; }
68+
>foo : { name: string; }[]
69+
>filter : { <S extends { name: string; }>(callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => unknown, thisArg?: any): { name: string; }[]; }
70+
>x => x.name : (x: { name: string; }) => string
71+
>x : { name: string; }
72+
>x.name : string
73+
>x : { name: string; }
74+
>name : string
75+
76+
var foos: Array<boolean>
77+
>foos : boolean[]
78+
79+
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
80+
>foos : boolean[]
81+
>[true, true, false, null].filter((thing): thing is boolean => thing !== null) : boolean[]
82+
>[true, true, false, null].filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => unknown, thisArg?: any): boolean[]; }
83+
>[true, true, false, null] : boolean[]
84+
>true : true
85+
>true : true
86+
>false : false
87+
>null : null
88+
>filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => unknown, thisArg?: any): boolean[]; }
89+
>(thing): thing is boolean => thing !== null : (thing: boolean) => thing is boolean
90+
>thing : boolean
91+
>thing !== null : boolean
92+
>thing : boolean
93+
>null : null
94+
Collapse file

‎tests/baselines/reference/typeGuardBoolean.js‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeGuardBoolean.js
-30Lines changed: 0 additions & 30 deletions
This file was deleted.
Collapse file

‎tests/baselines/reference/typeGuardBoolean.symbols‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeGuardBoolean.symbols
-35Lines changed: 0 additions & 35 deletions
This file was deleted.
Collapse file

‎tests/baselines/reference/typeGuardBoolean.types‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeGuardBoolean.types
-44Lines changed: 0 additions & 44 deletions
This file was deleted.
Collapse file
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
interface Bullean { }
2+
interface BulleanConstructor {
3+
new(v1?: any): Bullean;
4+
<T>(v2?: T): v2 is T;
5+
}
6+
7+
interface Ari<T> {
8+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
9+
filter(cb2: (value: T) => unknown): Ari<T>;
10+
}
11+
declare var Bullean: BulleanConstructor;
12+
declare let anys: Ari<any>;
13+
var xs: Ari<any>;
14+
var xs = anys.filter(Bullean)
15+
16+
declare let realanys: any[];
17+
var ys: any[];
18+
var ys = realanys.filter(Boolean)
19+
20+
var foo = [{ name: 'x' }]
21+
var foor: Array<{name: string}>
22+
var foor = foo.filter(x => x.name)
23+
var foos: Array<boolean>
24+
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.