Skip to content

Commit 04fbd93

Browse files
committed
Revert previous fix and improve error message instead
1 parent 1ad3285 commit 04fbd93

7 files changed

+67
-22
lines changed

src/compiler/checker.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9987,8 +9987,8 @@ namespace ts {
99879987
});
99889988
}
99899989

9990-
function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags, includeNonPublic?: boolean) {
9991-
if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
9990+
function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags) {
9991+
if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
99929992
let type = getLateBoundSymbol(prop).nameType;
99939993
if (!type && !isKnownSymbol(prop)) {
99949994
if (prop.escapedName === InternalSymbolName.Default) {
@@ -10006,8 +10006,8 @@ namespace ts {
1000610006
return neverType;
1000710007
}
1000810008

10009-
function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeNonPublic?: boolean) {
10010-
return getUnionType(map(getPropertiesOfType(type), p => getLiteralTypeFromProperty(p, include, includeNonPublic)));
10009+
function getLiteralTypeFromProperties(type: Type, include: TypeFlags) {
10010+
return getUnionType(map(getPropertiesOfType(type), p => getLiteralTypeFromProperty(p, include)));
1001110011
}
1001210012

1001310013
function getNonEnumNumberIndexInfo(type: Type) {
@@ -10023,10 +10023,10 @@ namespace ts {
1002310023
type === wildcardType ? wildcardType :
1002410024
type.flags & TypeFlags.Unknown ? neverType :
1002510025
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
10026-
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral, /*includeNonPublic*/ true) :
10027-
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol, /*includeNonPublic*/ true)]) :
10028-
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol, /*includeNonPublic*/ true)]) :
10029-
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true);
10026+
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
10027+
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
10028+
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
10029+
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique);
1003010030
}
1003110031

1003210032
function getExtractStringType(type: Type) {
@@ -10097,16 +10097,21 @@ namespace ts {
1009710097
return false;
1009810098
}
1009910099

10100-
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
10100+
function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
1010110101
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
10102-
const propName = isTypeUsableAsPropertyName(indexType) ?
10102+
return isTypeUsableAsPropertyName(indexType) ?
1010310103
getPropertyNameFromType(indexType) :
1010410104
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
1010510105
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
1010610106
accessNode && isPropertyName(accessNode) ?
1010710107
// late bound names are handled in the first branch, so here we only need to handle normal names
1010810108
getPropertyNameForPropertyNameNode(accessNode) :
1010910109
undefined;
10110+
}
10111+
10112+
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
10113+
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
10114+
const propName = getPropertyNameFromIndex(indexType, accessNode);
1011010115
if (propName !== undefined) {
1011110116
const prop = getPropertyOfType(objectType, propName);
1011210117
if (prop) {
@@ -25292,7 +25297,7 @@ namespace ts {
2529225297
forEach(node.types, checkSourceElement);
2529325298
}
2529425299

25295-
function checkIndexedAccessIndexType(type: Type, accessNode: Node) {
25300+
function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) {
2529625301
if (!(type.flags & TypeFlags.IndexedAccess)) {
2529725302
return type;
2529825303
}
@@ -25308,9 +25313,20 @@ namespace ts {
2530825313
}
2530925314
// Check if we're indexing with a numeric type and if either object or index types
2531025315
// is a generic type with a constraint that has a numeric index signature.
25311-
if (getIndexInfoOfType(getApparentType(objectType), IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
25316+
const apparentObjectType = getApparentType(objectType);
25317+
if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
2531225318
return type;
2531325319
}
25320+
if (isGenericObjectType(objectType)) {
25321+
const propertyName = getPropertyNameFromIndex(indexType, accessNode);
25322+
if (propertyName) {
25323+
const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
25324+
if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
25325+
error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
25326+
return errorType;
25327+
}
25328+
}
25329+
}
2531425330
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
2531525331
return errorType;
2531625332
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,10 @@
29632963
"category": "Error",
29642964
"code": 4104
29652965
},
2966+
"Private or protected member '{0}' cannot be accessed on a type parameter.": {
2967+
"category": "Error",
2968+
"code": 4105
2969+
},
29662970

29672971
"The current host does not support the '{0}' option.": {
29682972
"category": "Error",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,24): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
2+
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,32): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
3+
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(10,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
4+
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(11,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
5+
6+
7+
==== tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts (4 errors) ====
8+
class A {
9+
private a: number;
10+
}
11+
12+
class B {
13+
private a: string;
14+
}
15+
16+
type X<T extends A> = [T["a"], (T | B)["a"]];
17+
~~~~~~
18+
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
19+
~~~~~~~~~~~~
20+
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
21+
type Y<T extends A | B> = T["a"];
22+
~~~~~~
23+
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
24+
type Z<T extends A & B> = T["a"];
25+
~~~~~~
26+
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
27+

tests/baselines/reference/indexedAccessPrivateMemberOfGenericConstraint.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ class B {
77
private a: string;
88
}
99

10-
type X<T extends A> = T["a"];
10+
type X<T extends A> = [T["a"], (T | B)["a"]];
1111
type Y<T extends A | B> = T["a"];
1212
type Z<T extends A & B> = T["a"];
13-
1413

1514

1615
//// [indexedAccessPrivateMemberOfGenericConstraint.js]

tests/baselines/reference/indexedAccessPrivateMemberOfGenericConstraint.symbols

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ class B {
1313
>a : Symbol(B.a, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 4, 9))
1414
}
1515

16-
type X<T extends A> = T["a"];
16+
type X<T extends A> = [T["a"], (T | B)["a"]];
1717
>X : Symbol(X, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 6, 1))
1818
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
1919
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
2020
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
21+
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
22+
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
2123

2224
type Y<T extends A | B> = T["a"];
23-
>Y : Symbol(Y, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 29))
25+
>Y : Symbol(Y, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 45))
2426
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 9, 7))
2527
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
2628
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
@@ -33,4 +35,3 @@ type Z<T extends A & B> = T["a"];
3335
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
3436
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 10, 7))
3537

36-

tests/baselines/reference/indexedAccessPrivateMemberOfGenericConstraint.types

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ class B {
1313
>a : string
1414
}
1515

16-
type X<T extends A> = T["a"];
17-
>X : T["a"]
16+
type X<T extends A> = [T["a"], (T | B)["a"]];
17+
>X : [T["a"], (B | T)["a"]]
1818

1919
type Y<T extends A | B> = T["a"];
2020
>Y : T["a"]
2121

2222
type Z<T extends A & B> = T["a"];
2323
>Z : T["a"]
2424

25-

tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ class B {
66
private a: string;
77
}
88

9-
type X<T extends A> = T["a"];
9+
type X<T extends A> = [T["a"], (T | B)["a"]];
1010
type Y<T extends A | B> = T["a"];
1111
type Z<T extends A & B> = T["a"];
12-

0 commit comments

Comments
 (0)