Skip to content

Commit 154729d

Browse files
committed
Merge pull request microsoft#8770 from Microsoft/apparent-members-for-type-parameters-constrained-by-any
Apparent members for type parameters constrained by any
2 parents b70d079 + bc36f8c commit 154729d

File tree

4 files changed

+95
-18
lines changed

4 files changed

+95
-18
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9955,9 +9955,9 @@ namespace ts {
99559955
}
99569956

99579957
const apparentType = getApparentType(getWidenedType(type));
9958-
if (apparentType === unknownType) {
9959-
// handle cases when type is Type parameter with invalid constraint
9960-
return unknownType;
9958+
if (apparentType === unknownType || (type.flags & TypeFlags.TypeParameter && isTypeAny(apparentType))) {
9959+
// handle cases when type is Type parameter with invalid or any constraint
9960+
return apparentType;
99619961
}
99629962
const prop = getPropertyOfType(apparentType, right.text);
99639963
if (!prop) {
@@ -11148,7 +11148,9 @@ namespace ts {
1114811148
// types are provided for the argument expressions, and the result is always of type Any.
1114911149
// We exclude union types because we may have a union of function types that happen to have
1115011150
// no common signatures.
11151-
if (isTypeAny(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
11151+
if (isTypeAny(funcType) ||
11152+
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
11153+
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
1115211154
// The unknownType indicates that an error already occurred (and was reported). No
1115311155
// need to report another error in this case.
1115411156
if (funcType !== unknownType && node.typeArguments) {
Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Property 'blah' does not exist on type 'T'.
2-
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(9,7): error TS2339: Property 'blah' does not exist on type 'T'.
3-
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(10,7): error TS2339: Property 'toString' does not exist on type 'T'.
42

53

6-
==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (3 errors) ====
4+
==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (1 errors) ====
75
function fee<T>() {
86
var t: T;
97
t.blah; // Error
@@ -14,10 +12,28 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(10,7): error TS2339: P
1412

1513
function fee2<T extends any>() {
1614
var t: T;
17-
t.blah; // Error
18-
~~~~
19-
!!! error TS2339: Property 'blah' does not exist on type 'T'.
15+
t.blah; // ok
2016
t.toString; // ok
21-
~~~~~~~~
22-
!!! error TS2339: Property 'toString' does not exist on type 'T'.
23-
}
17+
}
18+
19+
function f<T extends any>(x: T) {
20+
x.children;
21+
x();
22+
new x();
23+
x[100];
24+
x['hello'];
25+
}
26+
27+
28+
// Generic Tree structure
29+
type Tree<T> = T & {
30+
children?: Tree<T>[];
31+
}
32+
33+
class MyClass {
34+
public static displayTree1<T extends Tree<any>>(tree: T) {
35+
// error "Property 'children' does not exist on type 'T'"
36+
tree.children;
37+
}
38+
}
39+

tests/baselines/reference/typeParameterExplicitlyExtendsAny.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,31 @@ function fee<T>() {
77

88
function fee2<T extends any>() {
99
var t: T;
10-
t.blah; // Error
10+
t.blah; // ok
1111
t.toString; // ok
12-
}
12+
}
13+
14+
function f<T extends any>(x: T) {
15+
x.children;
16+
x();
17+
new x();
18+
x[100];
19+
x['hello'];
20+
}
21+
22+
23+
// Generic Tree structure
24+
type Tree<T> = T & {
25+
children?: Tree<T>[];
26+
}
27+
28+
class MyClass {
29+
public static displayTree1<T extends Tree<any>>(tree: T) {
30+
// error "Property 'children' does not exist on type 'T'"
31+
tree.children;
32+
}
33+
}
34+
1335

1436
//// [typeParameterExplicitlyExtendsAny.js]
1537
function fee() {
@@ -19,6 +41,22 @@ function fee() {
1941
}
2042
function fee2() {
2143
var t;
22-
t.blah; // Error
44+
t.blah; // ok
2345
t.toString; // ok
2446
}
47+
function f(x) {
48+
x.children;
49+
x();
50+
new x();
51+
x[100];
52+
x['hello'];
53+
}
54+
var MyClass = (function () {
55+
function MyClass() {
56+
}
57+
MyClass.displayTree1 = function (tree) {
58+
// error "Property 'children' does not exist on type 'T'"
59+
tree.children;
60+
};
61+
return MyClass;
62+
}());

tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ function fee<T>() {
66

77
function fee2<T extends any>() {
88
var t: T;
9-
t.blah; // Error
9+
t.blah; // ok
1010
t.toString; // ok
11-
}
11+
}
12+
13+
function f<T extends any>(x: T) {
14+
x.children;
15+
x();
16+
new x();
17+
x[100];
18+
x['hello'];
19+
}
20+
21+
22+
// Generic Tree structure
23+
type Tree<T> = T & {
24+
children?: Tree<T>[];
25+
}
26+
27+
class MyClass {
28+
public static displayTree1<T extends Tree<any>>(tree: T) {
29+
// error "Property 'children' does not exist on type 'T'"
30+
tree.children;
31+
}
32+
}

0 commit comments

Comments
 (0)