@@ -28,6 +28,56 @@ function f3<A, B extends A>(a: Invariant<A>, b: Invariant<B>) {
28
28
b = a ; // Error
29
29
}
30
30
31
+ // Extract<T, Function> is a T that is known to be a Function
32
+ function isFunction < T > ( value : T ) : value is Extract < T , Function > {
33
+ return typeof value === "function" ;
34
+ }
35
+
36
+ function getFunction < T > ( item : T ) {
37
+ if ( isFunction ( item ) ) {
38
+ return item ;
39
+ }
40
+ throw new Error ( ) ;
41
+ }
42
+
43
+ function f10 < T > ( x : T ) {
44
+ if ( isFunction ( x ) ) {
45
+ const f : Function = x ;
46
+ const t : T = x ;
47
+ }
48
+ }
49
+
50
+ function f11 ( x : string | ( ( ) => string ) | undefined ) {
51
+ if ( isFunction ( x ) ) {
52
+ x ( ) ;
53
+ }
54
+ }
55
+
56
+ function f12 ( x : string | ( ( ) => string ) | undefined ) {
57
+ const f = getFunction ( x ) ; // () => string
58
+ f ( ) ;
59
+ }
60
+
61
+ type Foo = { foo : string } ;
62
+ type Bar = { bar : string } ;
63
+
64
+ declare function fooBar ( x : { foo : string , bar : string } ) : void ;
65
+ declare function fooBat ( x : { foo : string , bat : string } ) : void ;
66
+
67
+ type Extract2 < T , U , V > = T extends U ? T extends V ? T : never : never ;
68
+
69
+ function f20 < T > ( x : Extract < Extract < T , Foo > , Bar > , y : Extract < T , Foo & Bar > , z : Extract2 < T , Foo , Bar > ) {
70
+ fooBar ( x ) ;
71
+ fooBar ( y ) ;
72
+ fooBar ( z ) ;
73
+ }
74
+
75
+ function f21 < T > ( x : Extract < Extract < T , Foo > , Bar > , y : Extract < T , Foo & Bar > , z : Extract2 < T , Foo , Bar > ) {
76
+ fooBat ( x ) ; // Error
77
+ fooBat ( y ) ; // Error
78
+ fooBat ( z ) ; // Error
79
+ }
80
+
31
81
// Repros from #22860
32
82
33
83
class Opt < T > {
@@ -59,3 +109,15 @@ interface B1<T> extends A1<T> {
59
109
bat : B1 < B1 < T > > ;
60
110
boom : T extends any ? true : true
61
111
}
112
+
113
+ // Repro from #22899
114
+
115
+ declare function toString1 ( value : object | Function ) : string ;
116
+ declare function toString2 ( value : Function ) : string ;
117
+
118
+ function foo < T > ( value : T ) {
119
+ if ( isFunction ( value ) ) {
120
+ toString1 ( value ) ;
121
+ toString2 ( value ) ;
122
+ }
123
+ }
0 commit comments