@@ -2424,12 +2424,15 @@ namespace ts {
24242424 const visitedSymbolTables: SymbolTable[] = [];
24252425 return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
24262426
2427- function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable): Symbol[] | undefined {
2427+ /**
2428+ * @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
2429+ */
2430+ function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean): Symbol[] | undefined {
24282431 if (!pushIfUnique(visitedSymbolTables, symbols)) {
24292432 return undefined;
24302433 }
24312434
2432- const result = trySymbolTable(symbols);
2435+ const result = trySymbolTable(symbols, ignoreQualification );
24332436 visitedSymbolTables.pop();
24342437 return result;
24352438 }
@@ -2441,22 +2444,22 @@ namespace ts {
24412444 !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
24422445 }
24432446
2444- function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
2447+ function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol, ignoreQualification?: boolean ) {
24452448 return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
24462449 // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
24472450 // and if symbolFromSymbolTable or alias resolution matches the symbol,
24482451 // check the symbol can be qualified, it is only then this symbol is accessible
24492452 !some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
2450- canQualifySymbol(symbolFromSymbolTable, meaning);
2453+ (ignoreQualification || canQualifySymbol(symbolFromSymbolTable, meaning) );
24512454 }
24522455
24532456 function isUMDExportSymbol(symbol: Symbol) {
24542457 return symbol && symbol.declarations && symbol.declarations[0] && isNamespaceExportDeclaration(symbol.declarations[0]);
24552458 }
24562459
2457- function trySymbolTable(symbols: SymbolTable) {
2460+ function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined ) {
24582461 // If symbol is directly available by its name in the symbol table
2459- if (isAccessible(symbols.get(symbol.escapedName))) {
2462+ if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification )) {
24602463 return [symbol];
24612464 }
24622465
@@ -2469,14 +2472,14 @@ namespace ts {
24692472 && (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
24702473
24712474 const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
2472- if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
2475+ if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification )) {
24732476 return [symbolFromSymbolTable];
24742477 }
24752478
24762479 // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
24772480 // but only if the symbolFromSymbolTable can be qualified
24782481 const candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
2479- const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable);
2482+ const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true );
24802483 if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
24812484 return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
24822485 }
@@ -5995,7 +5998,9 @@ namespace ts {
59955998 for (const memberType of types) {
59965999 for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) {
59976000 if (!props.has(escapedName)) {
5998- props.set(escapedName, createUnionOrIntersectionProperty(unionType as UnionType, escapedName));
6001+ const prop = createUnionOrIntersectionProperty(unionType as UnionType, escapedName);
6002+ // May be undefined if the property is private
6003+ if (prop) props.set(escapedName, prop);
59996004 }
60006005 }
60016006 }
@@ -6177,7 +6182,7 @@ namespace ts {
61776182 t;
61786183 }
61796184
6180- function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol {
6185+ function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined {
61816186 let props: Symbol[];
61826187 const isUnion = containingType.flags & TypeFlags.Union;
61836188 const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
@@ -9220,7 +9225,8 @@ namespace ts {
92209225 isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
92219226
92229227 if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) {
9223- if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
9228+ const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
9229+ if (hasExcessProperties(<FreshObjectLiteralType>source, target, discriminantType, reportErrors)) {
92249230 if (reportErrors) {
92259231 reportRelationError(headMessage, source, target);
92269232 }
@@ -9230,7 +9236,7 @@ namespace ts {
92309236 // and intersection types are further deconstructed on the target side, we don't want to
92319237 // make the check again (as it might fail for a partial target type). Therefore we obtain
92329238 // the regular source type and proceed with that.
9233- if (isUnionOrIntersectionTypeWithoutNullableConstituents(target)) {
9239+ if (isUnionOrIntersectionTypeWithoutNullableConstituents(target) && !discriminantType ) {
92349240 source = getRegularTypeOfObjectLiteral(source);
92359241 }
92369242 }
@@ -9331,19 +9337,16 @@ namespace ts {
93319337 return Ternary.False;
93329338 }
93339339
9334- function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
9340+ function hasExcessProperties(source: FreshObjectLiteralType, target: Type, discriminant: Type | undefined, reportErrors: boolean): boolean {
93359341 if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
93369342 const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes);
93379343 if ((relation === assignableRelation || relation === comparableRelation) &&
93389344 (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
93399345 return false;
93409346 }
9341- if (target.flags & TypeFlags.Union) {
9342- const discriminantType = findMatchingDiscriminantType(source, target as UnionType);
9343- if (discriminantType) {
9344- // check excess properties against discriminant type only, not the entire union
9345- return hasExcessProperties(source, discriminantType, reportErrors);
9346- }
9347+ if (discriminant) {
9348+ // check excess properties against discriminant type only, not the entire union
9349+ return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors);
93479350 }
93489351 for (const prop of getPropertiesOfObjectType(source)) {
93499352 if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
@@ -13046,7 +13049,7 @@ namespace ts {
1304613049 node.parent.kind === SyntaxKind.NonNullExpression ||
1304713050 declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
1304813051 declaration.flags & NodeFlags.Ambient;
13049- const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration( declaration) as VariableLikeDeclaration) : type) :
13052+ const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) :
1305013053 type === autoType || type === autoArrayType ? undefinedType :
1305113054 getOptionalType(type);
1305213055 const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
@@ -15308,7 +15311,7 @@ namespace ts {
1530815311
1530915312 // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
1531015313 // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass.
15311- if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || (<ResolvedType>sourceAttributesType).properties .length > 0)) {
15314+ if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || getPropertiesOfType (<ResolvedType>sourceAttributesType).length > 0)) {
1531215315 error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName()));
1531315316 }
1531415317 else {
@@ -16715,7 +16718,7 @@ namespace ts {
1671516718 const isDecorator = node.kind === SyntaxKind.Decorator;
1671616719 const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
1671716720
16718- let typeArguments: ReadonlyArray <TypeNode>;
16721+ let typeArguments: NodeArray <TypeNode>;
1671916722
1672016723 if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
1672116724 typeArguments = (<CallExpression>node).typeArguments;
@@ -16844,7 +16847,7 @@ namespace ts {
1684416847 max = Math.max(max, length(sig.typeParameters));
1684516848 }
1684616849 const paramCount = min < max ? min + "-" + max : min;
16847- diagnostics.add(createDiagnosticForNode( node, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
16850+ diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode( node), typeArguments , Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
1684816851 }
1684916852 else if (args) {
1685016853 let min = Number.POSITIVE_INFINITY;
@@ -20964,7 +20967,7 @@ namespace ts {
2096420967 error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local));
2096520968 }
2096620969 }
20967- else if (compilerOptions.noUnusedLocals) {
20970+ else if (local.flags & SymbolFlags.TypeParameter ? compilerOptions.noUnusedParameters : compilerOptions.noUnusedLocals) {
2096820971 forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local)));
2096920972 }
2097020973 }
@@ -21028,6 +21031,7 @@ namespace ts {
2102821031 }
2102921032 break;
2103021033 case SyntaxKind.IndexSignature:
21034+ case SyntaxKind.SemicolonClassElement:
2103121035 // Can't be private
2103221036 break;
2103321037 default:
@@ -21038,7 +21042,7 @@ namespace ts {
2103821042 }
2103921043
2104021044 function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) {
21041- if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
21045+ if (compilerOptions.noUnusedParameters && !(node.flags & NodeFlags.Ambient)) {
2104221046 if (node.typeParameters) {
2104321047 // Only report errors on the last declaration for the type parameter container;
2104421048 // this ensures that all uses have been accounted for.
0 commit comments