Skip to content

Commit e118188

Browse files
committed
Add any constraint to Boolean factory function
I want to test how well this works.
1 parent f80dd7e commit e118188

File tree

6 files changed

+119
-42
lines changed

6 files changed

+119
-42
lines changed

src/lib/es5.d.ts

+2-2
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 extends any>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
517517
readonly prototype: Boolean;
518518
}
519519

@@ -1138,7 +1138,7 @@ interface ReadonlyArray<T> {
11381138
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
11391139
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
11401140
*/
1141-
filter(this: any[], callbackfn: (value: any, index: number, array: ReadonlyArray<any>) => unknown, thisArg?: any): any[];
1141+
filter(this: ReadonlyArray<never>, callbackfn: (value: any, index: number, array: ReadonlyArray<any>) => unknown, thisArg?: any): any[];
11421142
/**
11431143
* Returns the elements of an array that meet the condition specified in a callback function.
11441144
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.

tests/baselines/reference/booleanFilterAnyArray.errors.txt

-24
This file was deleted.

tests/baselines/reference/booleanFilterAnyArray.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface BulleanConstructor {
66
}
77

88
interface Ari<T> {
9-
filter<S extends T>(cb1: (value: T) => value is S): Ari<S>;
9+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
1010
filter(cb2: (value: T) => unknown): Ari<T>;
1111
}
1212
declare var Bullean: BulleanConstructor;
@@ -15,10 +15,23 @@ var xs: Ari<any>;
1515
var xs = anys.filter(Bullean)
1616

1717
declare let realanys: any[];
18+
var ys: any[];
1819
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)
1926

2027

2128
//// [booleanFilterAnyArray.js]
2229
var xs;
2330
var xs = anys.filter(Bullean);
31+
var ys;
2432
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; });

tests/baselines/reference/booleanFilterAnyArray.symbols

+42-6
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ interface Ari<T> {
2121
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
2222
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
2323

24-
filter<S extends T>(cb1: (value: T) => value is S): Ari<S>;
25-
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 63))
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))
2626
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
2727
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
2828
>cb1 : Symbol(cb1, Decl(booleanFilterAnyArray.ts, 7, 24))
2929
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
3030
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
3131
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
3232
>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))
3335
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
3436
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
3537

3638
filter(cb2: (value: T) => unknown): Ari<T>;
37-
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 63))
39+
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
3840
>cb2 : Symbol(cb2, Decl(booleanFilterAnyArray.ts, 8, 11))
3941
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 8, 17))
4042
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
@@ -55,18 +57,52 @@ var xs: Ari<any>;
5557

5658
var xs = anys.filter(Bullean)
5759
>xs : Symbol(xs, Decl(booleanFilterAnyArray.ts, 12, 3), Decl(booleanFilterAnyArray.ts, 13, 3))
58-
>anys.filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 63))
60+
>anys.filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
5961
>anys : Symbol(anys, Decl(booleanFilterAnyArray.ts, 11, 11))
60-
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 63))
62+
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
6163
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
6264

6365
declare let realanys: any[];
6466
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
6567

68+
var ys: any[];
69+
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
70+
6671
var ys = realanys.filter(Boolean)
67-
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3))
72+
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
6873
>realanys.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
6974
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
7075
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
7176
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
7277

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+

tests/baselines/reference/booleanFilterAnyArray.types

+53-8
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ interface BulleanConstructor {
99
}
1010

1111
interface Ari<T> {
12-
filter<S extends T>(cb1: (value: T) => value is S): Ari<S>;
13-
>filter : { <S extends T>(cb1: (value: T) => value is S): Ari<S>; (cb2: (value: T) => unknown): 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>; }
1414
>cb1 : (value: T) => value is S
1515
>value : T
1616

1717
filter(cb2: (value: T) => unknown): Ari<T>;
18-
>filter : { <S extends T>(cb1: (value: T) => value is S): Ari<S>; (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>; }
1919
>cb2 : (value: T) => unknown
2020
>value : T
2121
}
@@ -30,20 +30,65 @@ var xs: Ari<any>;
3030

3131
var xs = anys.filter(Bullean)
3232
>xs : Ari<any>
33-
>anys.filter(Bullean) : Ari<unknown>
34-
>anys.filter : { <S extends any>(cb1: (value: any) => value is S): Ari<S>; (cb2: (value: any) => unknown): 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>; }
3535
>anys : Ari<any>
36-
>filter : { <S extends any>(cb1: (value: any) => value is S): Ari<S>; (cb2: (value: any) => unknown): Ari<any>; }
36+
>filter : { <S extends any>(cb1: (value: any) => value is S): Ari<any>; (cb2: (value: any) => unknown): Ari<any>; }
3737
>Bullean : BulleanConstructor
3838

3939
declare let realanys: any[];
4040
>realanys : any[]
4141

42+
var ys: any[];
43+
>ys : any[]
44+
4245
var ys = realanys.filter(Boolean)
43-
>ys : unknown[]
44-
>realanys.filter(Boolean) : unknown[]
46+
>ys : any[]
47+
>realanys.filter(Boolean) : any[]
4548
>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[]; }
4649
>realanys : any[]
4750
>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[]; }
4851
>Boolean : BooleanConstructor
4952

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+

tests/cases/compiler/booleanFilterAnyArray.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ interface BulleanConstructor {
55
}
66

77
interface Ari<T> {
8-
filter<S extends T>(cb1: (value: T) => value is S): Ari<S>;
8+
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
99
filter(cb2: (value: T) => unknown): Ari<T>;
1010
}
1111
declare var Bullean: BulleanConstructor;
@@ -14,4 +14,11 @@ var xs: Ari<any>;
1414
var xs = anys.filter(Bullean)
1515

1616
declare let realanys: any[];
17+
var ys: any[];
1718
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)