Revert previous fix and improve error message instead

This commit is contained in:
Andrew Branch 2019-06-17 15:21:21 -07:00
parent 1ad3285701
commit 04fbd93bf8
No known key found for this signature in database
GPG Key ID: 22CCA4B120C427D2
7 changed files with 67 additions and 22 deletions

View File

@ -9987,8 +9987,8 @@ namespace ts {
});
}
function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags, includeNonPublic?: boolean) {
if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags) {
if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
let type = getLateBoundSymbol(prop).nameType;
if (!type && !isKnownSymbol(prop)) {
if (prop.escapedName === InternalSymbolName.Default) {
@ -10006,8 +10006,8 @@ namespace ts {
return neverType;
}
function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeNonPublic?: boolean) {
return getUnionType(map(getPropertiesOfType(type), p => getLiteralTypeFromProperty(p, include, includeNonPublic)));
function getLiteralTypeFromProperties(type: Type, include: TypeFlags) {
return getUnionType(map(getPropertiesOfType(type), p => getLiteralTypeFromProperty(p, include)));
}
function getNonEnumNumberIndexInfo(type: Type) {
@ -10023,10 +10023,10 @@ namespace ts {
type === wildcardType ? wildcardType :
type.flags & TypeFlags.Unknown ? neverType :
type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral, /*includeNonPublic*/ true) :
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol, /*includeNonPublic*/ true)]) :
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol, /*includeNonPublic*/ true)]) :
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true);
stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
!noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique);
}
function getExtractStringType(type: Type) {
@ -10097,9 +10097,9 @@ namespace ts {
return false;
}
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
const propName = isTypeUsableAsPropertyName(indexType) ?
return isTypeUsableAsPropertyName(indexType) ?
getPropertyNameFromType(indexType) :
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
@ -10107,6 +10107,11 @@ namespace ts {
// late bound names are handled in the first branch, so here we only need to handle normal names
getPropertyNameForPropertyNameNode(accessNode) :
undefined;
}
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
const propName = getPropertyNameFromIndex(indexType, accessNode);
if (propName !== undefined) {
const prop = getPropertyOfType(objectType, propName);
if (prop) {
@ -25292,7 +25297,7 @@ namespace ts {
forEach(node.types, checkSourceElement);
}
function checkIndexedAccessIndexType(type: Type, accessNode: Node) {
function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) {
if (!(type.flags & TypeFlags.IndexedAccess)) {
return type;
}
@ -25308,9 +25313,20 @@ namespace ts {
}
// Check if we're indexing with a numeric type and if either object or index types
// is a generic type with a constraint that has a numeric index signature.
if (getIndexInfoOfType(getApparentType(objectType), IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
const apparentObjectType = getApparentType(objectType);
if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
return type;
}
if (isGenericObjectType(objectType)) {
const propertyName = getPropertyNameFromIndex(indexType, accessNode);
if (propertyName) {
const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
return errorType;
}
}
}
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
return errorType;
}

View File

@ -2963,6 +2963,10 @@
"category": "Error",
"code": 4104
},
"Private or protected member '{0}' cannot be accessed on a type parameter.": {
"category": "Error",
"code": 4105
},
"The current host does not support the '{0}' option.": {
"category": "Error",

View File

@ -0,0 +1,27 @@
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,24): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,32): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(10,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(11,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
==== tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts (4 errors) ====
class A {
private a: number;
}
class B {
private a: string;
}
type X<T extends A> = [T["a"], (T | B)["a"]];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
~~~~~~~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
type Y<T extends A | B> = T["a"];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
type Z<T extends A & B> = T["a"];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.

View File

@ -7,10 +7,9 @@ class B {
private a: string;
}
type X<T extends A> = T["a"];
type X<T extends A> = [T["a"], (T | B)["a"]];
type Y<T extends A | B> = T["a"];
type Z<T extends A & B> = T["a"];
//// [indexedAccessPrivateMemberOfGenericConstraint.js]

View File

@ -13,14 +13,16 @@ class B {
>a : Symbol(B.a, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 4, 9))
}
type X<T extends A> = T["a"];
type X<T extends A> = [T["a"], (T | B)["a"]];
>X : Symbol(X, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 6, 1))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
type Y<T extends A | B> = T["a"];
>Y : Symbol(Y, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 29))
>Y : Symbol(Y, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 45))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 9, 7))
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
@ -33,4 +35,3 @@ type Z<T extends A & B> = T["a"];
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 10, 7))

View File

@ -13,8 +13,8 @@ class B {
>a : string
}
type X<T extends A> = T["a"];
>X : T["a"]
type X<T extends A> = [T["a"], (T | B)["a"]];
>X : [T["a"], (B | T)["a"]]
type Y<T extends A | B> = T["a"];
>Y : T["a"]
@ -22,4 +22,3 @@ type Y<T extends A | B> = T["a"];
type Z<T extends A & B> = T["a"];
>Z : T["a"]

View File

@ -6,7 +6,6 @@ class B {
private a: string;
}
type X<T extends A> = T["a"];
type X<T extends A> = [T["a"], (T | B)["a"]];
type Y<T extends A | B> = T["a"];
type Z<T extends A & B> = T["a"];