@@ -94,8 +94,6 @@ namespace ts {
9494
9595 const globalThisSymbol = createSymbol(SymbolFlags.Module, "globalThis" as __String, CheckFlags.Readonly);
9696 globalThisSymbol.exports = globals;
97- globalThisSymbol.valueDeclaration = createNode(SyntaxKind.Identifier) as Identifier;
98- (globalThisSymbol.valueDeclaration as Identifier).escapedText = "globalThis" as __String;
9997 globals.set(globalThisSymbol.escapedName, globalThisSymbol);
10098
10199 const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String);
@@ -926,7 +924,12 @@ namespace ts {
926924 recordMergedSymbol(target, source);
927925 }
928926 else if (target.flags & SymbolFlags.NamespaceModule) {
929- error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
927+ // Do not report an error when merging `var globalThis` with the built-in `globalThis`,
928+ // as we will already report a "Declaration name conflicts..." error, and this error
929+ // won't make much sense.
930+ if (target !== globalThisSymbol) {
931+ error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
932+ }
930933 }
931934 else { // error
932935 const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum);
@@ -1409,15 +1412,14 @@ namespace ts {
14091412 }
14101413 break;
14111414 case SyntaxKind.PropertyDeclaration:
1412- case SyntaxKind.PropertySignature:
14131415 // TypeScript 1.0 spec (April 2014): 8.4.1
14141416 // Initializer expressions for instance member variables are evaluated in the scope
14151417 // of the class constructor body but are not permitted to reference parameters or
14161418 // local variables of the constructor. This effectively means that entities from outer scopes
14171419 // by the same name as a constructor parameter or local variable are inaccessible
14181420 // in initializer expressions for instance member variables.
1419- if (isClassLike(location.parent) && !hasModifier(location, ModifierFlags.Static)) {
1420- const ctor = findConstructorDeclaration(location.parent);
1421+ if (!hasModifier(location, ModifierFlags.Static)) {
1422+ const ctor = findConstructorDeclaration(location.parent as ClassLikeDeclaration );
14211423 if (ctor && ctor.locals) {
14221424 if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) {
14231425 // Remember the property node, it will be used later to report appropriate error
@@ -9943,13 +9945,13 @@ namespace ts {
99439945 return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
99449946 type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
99459947 maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
9946- getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number ))) :
9948+ getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(<MappedType>type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) :
99479949 type === wildcardType ? wildcardType :
99489950 type.flags & TypeFlags.Unknown ? neverType :
99499951 type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType :
99509952 stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) :
99519953 !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) :
9952- !noIndexSignatures && getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
9954+ getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) :
99539955 getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique);
99549956 }
99559957
@@ -10067,10 +10069,10 @@ namespace ts {
1006710069 if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) {
1006810070 return objectType;
1006910071 }
10070- const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
10071- getIndexInfoOfType(objectType, IndexKind.String) ;
10072+ const stringIndexInfo = getIndexInfoOfType(objectType, IndexKind.String);
10073+ const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || stringIndexInfo ;
1007210074 if (indexInfo) {
10073- if (accessFlags & AccessFlags.NoIndexSignatures) {
10075+ if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo ) {
1007410076 if (accessExpression) {
1007510077 error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
1007610078 }
@@ -14228,6 +14230,32 @@ namespace ts {
1422814230 return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
1422914231 }
1423014232
14233+
14234+ /**
14235+ * Is source potentially coercible to target type under `==`.
14236+ * Assumes that `source` is a constituent of a union, hence
14237+ * the boolean literal flag on the LHS, but not on the RHS.
14238+ *
14239+ * This does not fully replicate the semantics of `==`. The
14240+ * intention is to catch cases that are clearly not right.
14241+ *
14242+ * Comparing (string | number) to number should not remove the
14243+ * string element.
14244+ *
14245+ * Comparing (string | number) to 1 will remove the string
14246+ * element, though this is not sound. This is a pragmatic
14247+ * choice.
14248+ *
14249+ * @see narrowTypeByEquality
14250+ *
14251+ * @param source
14252+ * @param target
14253+ */
14254+ function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean {
14255+ return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0)
14256+ && ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0);
14257+ }
14258+
1423114259 /**
1423214260 * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
1423314261 * with no call or construct signatures.
@@ -16571,7 +16599,10 @@ namespace ts {
1657116599 return type;
1657216600 }
1657316601 if (assumeTrue) {
16574- const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
16602+ const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ?
16603+ (t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType)) :
16604+ t => areTypesComparable(t, valueType);
16605+ const narrowedType = filterType(type, filterFn);
1657516606 return narrowedType.flags & TypeFlags.Never ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
1657616607 }
1657716608 if (isUnitType(valueType)) {
@@ -21973,6 +22004,13 @@ namespace ts {
2197322004 const arg = (<PrefixUnaryExpression>node).operand;
2197422005 return op === SyntaxKind.MinusToken && (arg.kind === SyntaxKind.NumericLiteral || arg.kind === SyntaxKind.BigIntLiteral) ||
2197522006 op === SyntaxKind.PlusToken && arg.kind === SyntaxKind.NumericLiteral;
22007+ case SyntaxKind.PropertyAccessExpression:
22008+ case SyntaxKind.ElementAccessExpression:
22009+ const expr = (<PropertyAccessExpression | ElementAccessExpression>node).expression;
22010+ if (isIdentifier(expr)) {
22011+ const symbol = getSymbolAtLocation(expr);
22012+ return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal);
22013+ }
2197622014 }
2197722015 return false;
2197822016 }
@@ -21981,7 +22019,7 @@ namespace ts {
2198122019 let exprType = checkExpression(expression, checkMode);
2198222020 if (isConstTypeReference(type)) {
2198322021 if (!isValidConstAssertionArgument(expression)) {
21984- error(expression, Diagnostics.A_const_assertion_can_only_be_applied_to_a_string_number_boolean_array_or_object_literal );
22022+ error(expression, Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals );
2198522023 }
2198622024 return getRegularTypeOfLiteralType(exprType);
2198722025 }
@@ -25629,7 +25667,7 @@ namespace ts {
2562925667 }
2563025668
2563125669 if (!compilerOptions.experimentalDecorators) {
25632- error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning );
25670+ error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning );
2563325671 }
2563425672
2563525673 const firstDecorator = node.decorators[0];
@@ -26427,14 +26465,28 @@ namespace ts {
2642726465 }
2642826466 // For a binding pattern, validate the initializer and exit
2642926467 if (isBindingPattern(node.name)) {
26430- // Don't validate for-in initializer as it is already an error
26431- if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
26432- const initializerType = checkExpressionCached(node.initializer);
26433- if (strictNullChecks && node.name.elements.length === 0) {
26434- checkNonNullNonVoidType(initializerType, node);
26468+ const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
26469+ const needCheckWidenedType = node.name.elements.length === 0;
26470+ if (needCheckInitializer || needCheckWidenedType) {
26471+ // Don't validate for-in initializer as it is already an error
26472+ const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
26473+ if (needCheckInitializer) {
26474+ const initializerType = checkExpressionCached(node.initializer!);
26475+ if (strictNullChecks && needCheckWidenedType) {
26476+ checkNonNullNonVoidType(initializerType, node);
26477+ }
26478+ else {
26479+ checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26480+ }
2643526481 }
26436- else {
26437- checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26482+ // check the binding pattern with empty elements
26483+ if (needCheckWidenedType) {
26484+ if (isArrayBindingPattern(node.name)) {
26485+ checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
26486+ }
26487+ else if (strictNullChecks) {
26488+ checkNonNullNonVoidType(widenedType, node);
26489+ }
2643826490 }
2643926491 }
2644026492 return;
@@ -30407,6 +30459,14 @@ namespace ts {
3040730459 continue;
3040830460 }
3040930461 if (!isExternalOrCommonJsModule(file)) {
30462+ // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
30463+ // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
30464+ const fileGlobalThisSymbol = file.locals!.get("globalThis" as __String);
30465+ if (fileGlobalThisSymbol) {
30466+ for (const declaration of fileGlobalThisSymbol.declarations) {
30467+ diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
30468+ }
30469+ }
3041030470 mergeSymbolTable(globals, file.locals!);
3041130471 }
3041230472 if (file.jsGlobalAugmentations) {
@@ -30452,6 +30512,7 @@ namespace ts {
3045230512 getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
3045330513 getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true);
3045430514 getSymbolLinks(unknownSymbol).type = errorType;
30515+ getSymbolLinks(globalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, globalThisSymbol);
3045530516
3045630517 // Initialize special types
3045730518 globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true);
@@ -31179,6 +31240,13 @@ namespace ts {
3117931240
3118031241 for (const prop of node.properties) {
3118131242 if (prop.kind === SyntaxKind.SpreadAssignment) {
31243+ if (inDestructuring) {
31244+ // a rest property cannot be destructured any further
31245+ const expression = skipParentheses(prop.expression);
31246+ if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
31247+ return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
31248+ }
31249+ }
3118231250 continue;
3118331251 }
3118431252 const name = prop.name;
@@ -31841,7 +31909,7 @@ namespace ts {
3184131909 return false;
3184231910 }
3184331911
31844- return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file );
31912+ return grammarErrorOnFirstToken(node, Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier );
3184531913 }
3184631914
3184731915 function checkGrammarTopLevelElementsForRequiredDeclareModifier(file: SourceFile): boolean {
0 commit comments