@@ -10099,16 +10099,21 @@ namespace ts {
1009910099 return false;
1010010100 }
1010110101
10102- function getPropertyTypeForIndexType(originalObjectType : Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags ) {
10102+ function getPropertyNameFromIndex(indexType : Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
1010310103 const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
10104- const propName = isTypeUsableAsPropertyName(indexType) ?
10104+ return isTypeUsableAsPropertyName(indexType) ?
1010510105 getPropertyNameFromType(indexType) :
1010610106 accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
1010710107 getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
1010810108 accessNode && isPropertyName(accessNode) ?
1010910109 // late bound names are handled in the first branch, so here we only need to handle normal names
1011010110 getPropertyNameForPropertyNameNode(accessNode) :
1011110111 undefined;
10112+ }
10113+
10114+ function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
10115+ const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
10116+ const propName = getPropertyNameFromIndex(indexType, accessNode);
1011210117 if (propName !== undefined) {
1011310118 const prop = getPropertyOfType(objectType, propName);
1011410119 if (prop) {
@@ -13314,7 +13319,14 @@ namespace ts {
1331413319 }
1331513320 }
1331613321 else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
13317- return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors);
13322+ if (relation !== identityRelation) {
13323+ return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors);
13324+ }
13325+ else {
13326+ // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple
13327+ // or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction
13328+ return Ternary.False;
13329+ }
1331813330 }
1331913331 // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})`
1332013332 // and not `{} <- fresh({}) <- {[idx: string]: any}`
@@ -20018,6 +20030,7 @@ namespace ts {
2001820030 }
2001920031
2002020032 function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) {
20033+ checkGrammarJsxExpression(node);
2002120034 if (node.expression) {
2002220035 const type = checkExpression(node.expression, checkMode);
2002320036 if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
@@ -22494,7 +22507,10 @@ namespace ts {
2249422507 case SyntaxKind.ElementAccessExpression:
2249522508 const expr = (<PropertyAccessExpression | ElementAccessExpression>node).expression;
2249622509 if (isIdentifier(expr)) {
22497- const symbol = getSymbolAtLocation(expr);
22510+ let symbol = getSymbolAtLocation(expr);
22511+ if (symbol && symbol.flags & SymbolFlags.Alias) {
22512+ symbol = resolveAlias(symbol);
22513+ }
2249822514 return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal);
2249922515 }
2250022516 }
@@ -25321,7 +25337,7 @@ namespace ts {
2532125337 forEach(node.types, checkSourceElement);
2532225338 }
2532325339
25324- function checkIndexedAccessIndexType(type: Type, accessNode: Node ) {
25340+ function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression ) {
2532525341 if (!(type.flags & TypeFlags.IndexedAccess)) {
2532625342 return type;
2532725343 }
@@ -25337,9 +25353,20 @@ namespace ts {
2533725353 }
2533825354 // Check if we're indexing with a numeric type and if either object or index types
2533925355 // is a generic type with a constraint that has a numeric index signature.
25340- if (getIndexInfoOfType(getApparentType(objectType), IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
25356+ const apparentObjectType = getApparentType(objectType);
25357+ if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
2534125358 return type;
2534225359 }
25360+ if (isGenericObjectType(objectType)) {
25361+ const propertyName = getPropertyNameFromIndex(indexType, accessNode);
25362+ if (propertyName) {
25363+ const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
25364+ if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
25365+ error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
25366+ return errorType;
25367+ }
25368+ }
25369+ }
2534325370 error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
2534425371 return errorType;
2534525372 }
@@ -31889,6 +31916,12 @@ namespace ts {
3188931916 }
3189031917 }
3189131918
31919+ function checkGrammarJsxExpression(node: JsxExpression) {
31920+ if (node.expression && isCommaSequence(node.expression)) {
31921+ return grammarErrorOnNode(node.expression, Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array);
31922+ }
31923+ }
31924+
3189231925 function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean {
3189331926 if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
3189431927 return true;
0 commit comments