From e813bb07c3240782afc0634a81438d625577c990 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Fri, 9 Jan 2026 23:01:01 +0100 Subject: [PATCH 1/3] fix(checker): Allow element access expressions in computed property names if argument is literal --- src/compiler/checker.ts | 20 ++++++++++--- tests/cases/compiler/enumKeysInTypeLiteral.ts | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 tests/cases/compiler/enumKeysInTypeLiteral.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2523d3baaba55..5dc439aba20b3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -742,6 +742,7 @@ import { isShorthandAmbientModuleSymbol, isShorthandPropertyAssignment, isSideEffectImport, + isSignedNumericLiteral, isSingleOrDoubleQuote, isSourceFile, isSourceFileJS, @@ -13720,14 +13721,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { && isTypeUsableAsIndexSignature(isComputedPropertyName(node) ? checkComputedPropertyName(node) : checkExpressionCached((node as ElementAccessExpression).argumentExpression)); } - function isLateBindableAST(node: DeclarationName) { - if (!isComputedPropertyName(node) && !isElementAccessExpression(node)) { - return false; + function isLateBindableExpression(expr: Expression): boolean { + while (isElementAccessExpression(expr)) { + const argument = skipParentheses(expr.argumentExpression); + if (!isStringOrNumericLiteralLike(argument) && !isSignedNumericLiteral(argument)) return false; + expr = expr.expression; } - const expr = isComputedPropertyName(node) ? node.expression : node.argumentExpression; return isEntityNameExpression(expr); } + function isLateBindableAST(node: DeclarationName) { + if (isComputedPropertyName(node)) { + return isLateBindableExpression(node.expression); + } + else if (isElementAccessExpression(node)) { + return isLateBindableExpression(node.argumentExpression); + } + return false; + } + function isTypeUsableAsIndexSignature(type: Type): boolean { return isTypeAssignableTo(type, stringNumberSymbolType); } diff --git a/tests/cases/compiler/enumKeysInTypeLiteral.ts b/tests/cases/compiler/enumKeysInTypeLiteral.ts new file mode 100644 index 0000000000000..481108289449b --- /dev/null +++ b/tests/cases/compiler/enumKeysInTypeLiteral.ts @@ -0,0 +1,29 @@ + +enum Type { + Foo = 'foo', + '3x14' = '3x14' +} + +type TypeMap = { + [Type.Foo]: 1; + [Type['3x14']]: 2; +} + +const t: TypeMap = { + 'foo': 1, + '3x14': 2 +}; + +enum Numeric { + Negative = -1, + Zero = 0 +} + +type NumericMap = { + // Valid: Accessing enum member via string literal for the name + [Numeric['Negative']]: number; + [Numeric['Zero']]: number; + // Valid: Parenthesized access + [Numeric[('Negative')]]: number; +} + From 91424d844adb355c2252a6a2309155e04080bc67 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Thu, 15 Jan 2026 17:37:50 +0100 Subject: [PATCH 2/3] fix(checker): Allow element access expressions in computed property names if argument is literal --- src/compiler/utilities.ts | 202 +++++++++--------- .../reference/enumKeysInTypeLiteral.js | 48 +++++ .../reference/enumKeysInTypeLiteral.symbols | 71 ++++++ .../reference/enumKeysInTypeLiteral.types | 124 +++++++++++ .../isolatedDeclarationLazySymbols.errors.txt | 6 +- .../isolatedDeclarationLazySymbols.types | 4 +- 6 files changed, 353 insertions(+), 102 deletions(-) create mode 100644 tests/baselines/reference/enumKeysInTypeLiteral.js create mode 100644 tests/baselines/reference/enumKeysInTypeLiteral.symbols create mode 100644 tests/baselines/reference/enumKeysInTypeLiteral.types diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ba6b6d253a31c..e8cdab41cf5a2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -811,13 +811,13 @@ export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleWithFaile return oldResolution === newResolution || oldResolution.resolvedModule === newResolution.resolvedModule || !!oldResolution.resolvedModule && - !!newResolution.resolvedModule && - oldResolution.resolvedModule.isExternalLibraryImport === newResolution.resolvedModule.isExternalLibraryImport && - oldResolution.resolvedModule.extension === newResolution.resolvedModule.extension && - oldResolution.resolvedModule.resolvedFileName === newResolution.resolvedModule.resolvedFileName && - oldResolution.resolvedModule.originalPath === newResolution.resolvedModule.originalPath && - packageIdIsEqual(oldResolution.resolvedModule.packageId, newResolution.resolvedModule.packageId) && - oldResolution.alternateResult === newResolution.alternateResult; + !!newResolution.resolvedModule && + oldResolution.resolvedModule.isExternalLibraryImport === newResolution.resolvedModule.isExternalLibraryImport && + oldResolution.resolvedModule.extension === newResolution.resolvedModule.extension && + oldResolution.resolvedModule.resolvedFileName === newResolution.resolvedModule.resolvedFileName && + oldResolution.resolvedModule.originalPath === newResolution.resolvedModule.originalPath && + packageIdIsEqual(oldResolution.resolvedModule.packageId, newResolution.resolvedModule.packageId) && + oldResolution.alternateResult === newResolution.alternateResult; } /** @internal */ @@ -846,25 +846,25 @@ export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeChec ...alternateResultMessage[1], ) : host.typesPackageExists(packageName) - ? chainDiagnosticMessages( + ? chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, - packageName, - mangleScopedPackageName(packageName), - ) - : host.packageBundlesTypes(packageName) - ? chainDiagnosticMessages( + Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, + packageName, + mangleScopedPackageName(packageName), + ) + : host.packageBundlesTypes(packageName) + ? chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, - packageName, - moduleReference, - ) - : chainDiagnosticMessages( + Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, + packageName, + moduleReference, + ) + : chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, - moduleReference, - mangleScopedPackageName(packageName), - ); + Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, + moduleReference, + mangleScopedPackageName(packageName), + ); if (result) result.repopulateInfo = () => ({ moduleReference, mode, packageName: packageName === moduleReference ? undefined : packageName }); return result; } @@ -888,15 +888,15 @@ export function createModeMismatchDetails(currentSourceFile: SourceFile): Diagno combinePaths(scope.packageDirectory, "package.json"), ) : targetExt ? - chainDiagnosticMessages( + chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_package_json_file_with_type_Colon_module, - targetExt, - ) : - chainDiagnosticMessages( + Diagnostics.To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_package_json_file_with_type_Colon_module, + targetExt, + ) : + chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module, - ); + Diagnostics.To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module, + ); result.repopulateInfo = () => true; return result; } @@ -920,10 +920,10 @@ export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirec return oldResolution === newResolution || oldResolution.resolvedTypeReferenceDirective === newResolution.resolvedTypeReferenceDirective || !!oldResolution.resolvedTypeReferenceDirective && - !!newResolution.resolvedTypeReferenceDirective && - oldResolution.resolvedTypeReferenceDirective.resolvedFileName === newResolution.resolvedTypeReferenceDirective.resolvedFileName && - !!oldResolution.resolvedTypeReferenceDirective.primary === !!newResolution.resolvedTypeReferenceDirective.primary && - oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; + !!newResolution.resolvedTypeReferenceDirective && + oldResolution.resolvedTypeReferenceDirective.resolvedFileName === newResolution.resolvedTypeReferenceDirective.resolvedFileName && + !!oldResolution.resolvedTypeReferenceDirective.primary === !!newResolution.resolvedTypeReferenceDirective.primary && + oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; } /** @internal */ @@ -1189,11 +1189,11 @@ export function isRecognizedTripleSlashComment(text: string, commentPos: number, ) { const textSubStr = text.substring(commentPos, commentEnd); return fullTripleSlashReferencePathRegEx.test(textSubStr) || - fullTripleSlashAMDReferencePathRegEx.test(textSubStr) || - fullTripleSlashAMDModuleRegEx.test(textSubStr) || - fullTripleSlashReferenceTypeReferenceDirectiveRegEx.test(textSubStr) || - fullTripleSlashLibReferenceRegEx.test(textSubStr) || - defaultLibReferenceRegEx.test(textSubStr) ? + fullTripleSlashAMDReferencePathRegEx.test(textSubStr) || + fullTripleSlashAMDModuleRegEx.test(textSubStr) || + fullTripleSlashReferenceTypeReferenceDirectiveRegEx.test(textSubStr) || + fullTripleSlashLibReferenceRegEx.test(textSubStr) || + defaultLibReferenceRegEx.test(textSubStr) ? true : false; } return false; @@ -1943,7 +1943,7 @@ export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | u case SyntaxKind.StringLiteral: { const escapeText = flags & GetLiteralTextFlags.JsxAttributeEscape ? escapeJsxAttributeString : flags & GetLiteralTextFlags.NeverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : - escapeNonAsciiString; + escapeNonAsciiString; if ((node as StringLiteral).singleQuote) { return "'" + escapeText(node.text, CharacterCodes.singleQuote) + "'"; } @@ -2310,7 +2310,9 @@ export function getNameFromIndexInfo(info: IndexInfo): string | undefined { /** @internal */ export function isComputedNonLiteralName(name: PropertyName): boolean { - return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteralLike(name.expression); + return name.kind === SyntaxKind.ComputedPropertyName && + !isStringOrNumericLiteralLike(name.expression) && + !isSignedNumericLiteral(name.expression); } /** @internal */ @@ -2326,6 +2328,12 @@ export function tryGetTextOfPropertyName(name: PropertyName | NoSubstitutionTemp return escapeLeadingUnderscores(name.text); case SyntaxKind.ComputedPropertyName: if (isStringOrNumericLiteralLike(name.expression)) return escapeLeadingUnderscores(name.expression.text); + if (isSignedNumericLiteral(name.expression)) { + if (name.expression.operator === SyntaxKind.MinusToken) { + return tokenToString(name.expression.operator) + name.expression.operand.text as __String; + } + return name.expression.operand.text as __String; + } return undefined; case SyntaxKind.JsxNamespacedName: return getEscapedTextOfJsxNamespacedName(name); @@ -2715,12 +2723,12 @@ export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: Sour /** @internal */ export function getJSDocCommentRanges(node: Node, text: string): CommentRange[] | undefined { const commentRanges = (node.kind === SyntaxKind.Parameter || - node.kind === SyntaxKind.TypeParameter || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.ArrowFunction || - node.kind === SyntaxKind.ParenthesizedExpression || - node.kind === SyntaxKind.VariableDeclaration || - node.kind === SyntaxKind.ExportSpecifier) ? + node.kind === SyntaxKind.TypeParameter || + node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.ArrowFunction || + node.kind === SyntaxKind.ParenthesizedExpression || + node.kind === SyntaxKind.VariableDeclaration || + node.kind === SyntaxKind.ExportSpecifier) ? concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : getLeadingCommentRanges(text, node.pos); // True if the comment starts with '/**' but not if it is '/**/' @@ -2775,7 +2783,7 @@ export function isPartOfTypeNode(node: Node): boolean { } // At this point, node is either a qualified name or an identifier Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'."); - // falls through + // falls through case SyntaxKind.QualifiedName: case SyntaxKind.PropertyAccessExpression: @@ -2986,7 +2994,7 @@ export function isCommonJsExportPropertyAssignment(node: Node): boolean { export function isValidESSymbolDeclaration(node: Node): boolean { return (isVariableDeclaration(node) ? isVarConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : isPropertyDeclaration(node) ? hasEffectiveReadonlyModifier(node) && hasStaticModifier(node) : - isPropertySignature(node) && hasEffectiveReadonlyModifier(node)) || isCommonJsExportPropertyAssignment(node); + isPropertySignature(node) && hasEffectiveReadonlyModifier(node)) || isCommonJsExportPropertyAssignment(node); } /** @internal */ @@ -3179,7 +3187,7 @@ export function getThisContainer(node: Node, includeArrowFunctions: boolean, inc if (!includeArrowFunctions) { continue; } - // falls through + // falls through case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: @@ -3304,7 +3312,7 @@ export function getSuperContainer(node: Node, stopOnFunctions: boolean) { if (!stopOnFunctions) { continue; } - // falls through + // falls through case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: @@ -3532,7 +3540,7 @@ export function classElementOrClassElementParameterIsDecorated(useLegacyDecorato const { firstAccessor, secondAccessor, setAccessor } = getAllAccessorDeclarations(parent.members, node); const firstAccessorWithDecorators = hasDecorators(firstAccessor) ? firstAccessor : secondAccessor && hasDecorators(secondAccessor) ? secondAccessor : - undefined; + undefined; if (!firstAccessorWithDecorators || node !== firstAccessorWithDecorators) { return false; } @@ -3640,7 +3648,7 @@ export function isExpressionNode(node: Node): boolean { if (node.parent.kind === SyntaxKind.TypeQuery || isJSDocLinkLike(node.parent) || isJSDocNameReference(node.parent) || isJSDocMemberName(node.parent) || isJSXTagName(node)) { return true; } - // falls through + // falls through case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: @@ -3982,7 +3990,7 @@ function getDefaultedExpandoInitializer(name: Expression, initializer: Expressio export function isDefaultedExpandoInitializer(node: BinaryExpression): boolean | undefined { const name = isVariableDeclaration(node.parent) ? node.parent.name : isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken ? node.parent.left : - undefined; + undefined; return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left); } @@ -4022,9 +4030,9 @@ export function isSameEntityName(name: Expression, initializer: Expression): boo isMemberName(name) && isLiteralLikeAccess(initializer) && (initializer.expression.kind === SyntaxKind.ThisKeyword || isIdentifier(initializer.expression) && - (initializer.expression.escapedText === "window" || - initializer.expression.escapedText === "self" || - initializer.expression.escapedText === "global")) + (initializer.expression.escapedText === "window" || + initializer.expression.escapedText === "self" || + initializer.expression.escapedText === "global")) ) { return isSameEntityName(name, getNameOrArgument(initializer)); } @@ -4262,7 +4270,7 @@ export function setValueDeclaration(symbol: Symbol, node: Declaration): void { if ( !valueDeclaration || !(node.flags & NodeFlags.Ambient && !isInJSFile(node) && !(valueDeclaration.flags & NodeFlags.Ambient)) && - (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || + (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration)) ) { // other kinds of value declarations take precedence over modules and assignment declarations @@ -4443,18 +4451,18 @@ export function isTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallback function getSourceOfAssignment(node: Node): Node | undefined { return isExpressionStatement(node) && - isBinaryExpression(node.expression) && - node.expression.operatorToken.kind === SyntaxKind.EqualsToken + isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === SyntaxKind.EqualsToken ? getRightMostAssignedExpression(node.expression) : undefined; } function getSourceOfDefaultedAssignment(node: Node): Node | undefined { return isExpressionStatement(node) && - isBinaryExpression(node.expression) && - getAssignmentDeclarationKind(node.expression) !== AssignmentDeclarationKind.None && - isBinaryExpression(node.expression.right) && - (node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken || node.expression.right.operatorToken.kind === SyntaxKind.QuestionQuestionToken) + isBinaryExpression(node.expression) && + getAssignmentDeclarationKind(node.expression) !== AssignmentDeclarationKind.None && + isBinaryExpression(node.expression.right) && + (node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken || node.expression.right.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? node.expression.right.right : undefined; } @@ -4478,8 +4486,8 @@ export function getSingleVariableOfVariableStatement(node: Node): VariableDeclar function getNestedModuleDeclaration(node: Node): Node | undefined { return isModuleDeclaration(node) && - node.body && - node.body.kind === SyntaxKind.ModuleDeclaration + node.body && + node.body.kind === SyntaxKind.ModuleDeclaration ? node.body : undefined; } @@ -5036,7 +5044,7 @@ export function getDeclarationFromName(name: Node): Declaration | undefined { case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.NumericLiteral: if (isComputedPropertyName(parent)) return parent.parent; - // falls through + // falls through case SyntaxKind.Identifier: if (isDeclaration(parent)) { return parent.name === name ? parent : undefined; @@ -5048,9 +5056,9 @@ export function getDeclarationFromName(name: Node): Declaration | undefined { else { const binExp = parent.parent; return isBinaryExpression(binExp) && - getAssignmentDeclarationKind(binExp) !== AssignmentDeclarationKind.None && - ((binExp.left as BindableStaticNameExpression).symbol || binExp.symbol) && - getNameOfDeclaration(binExp) === name + getAssignmentDeclarationKind(binExp) !== AssignmentDeclarationKind.None && + ((binExp.left as BindableStaticNameExpression).symbol || binExp.symbol) && + getNameOfDeclaration(binExp) === name ? binExp : undefined; } @@ -5182,7 +5190,7 @@ export function getEffectiveImplementsTypeNodes(node: ClassLikeDeclaration): und export function getAllSuperTypeNodes(node: Node): readonly TypeNode[] { return isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || emptyArray : isClassLike(node) ? concatenate(singleElementArray(getEffectiveBaseTypeNode(node)), getEffectiveImplementsTypeNodes(node)) || emptyArray : - emptyArray; + emptyArray; } /** @internal */ @@ -5281,7 +5289,7 @@ export function getFunctionFlags(node: SignatureDeclaration | undefined): Functi if (node.asteriskToken) { flags |= FunctionFlags.Generator; } - // falls through + // falls through case SyntaxKind.ArrowFunction: if (hasSyntacticModifier(node, ModifierFlags.Async)) { @@ -6160,7 +6168,7 @@ function getReplacement(c: string, offset: number, input: string) { export function escapeString(s: string, quoteChar?: CharacterCodes.doubleQuote | CharacterCodes.singleQuote | CharacterCodes.backtick): string { const escapedCharsRegExp = quoteChar === CharacterCodes.backtick ? backtickQuoteEscapedCharsRegExp : quoteChar === CharacterCodes.singleQuote ? singleQuoteEscapedCharsRegExp : - doubleQuoteEscapedCharsRegExp; + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } @@ -6523,8 +6531,8 @@ export function getDeclarationEmitOutputFilePathWorker(fileName: string, options export function getDeclarationEmitExtensionForPath(path: string): Extension.Dts | Extension.Dmts | Extension.Dcts | ".d.json.ts" { return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : - fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well - Extension.Dts; + fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well + Extension.Dts; } /** @@ -6535,8 +6543,8 @@ export function getDeclarationEmitExtensionForPath(path: string): Extension.Dts export function getPossibleOriginalInputExtensionForExtension(path: string): Extension[] { return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] : fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs] : - fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : - [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; + fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : + [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; } /** @internal */ @@ -8007,7 +8015,7 @@ export function getDeclarationModifierFlagsFromSymbol(s: Symbol, isWrite = false const checkFlags = (s as TransientSymbol).links.checkFlags; const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private : checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public : - ModifierFlags.Protected; + ModifierFlags.Protected; const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0; return accessModifier | staticModifier; } @@ -8393,7 +8401,7 @@ export function getLeftmostExpression(node: Expression, stopAtCallExpressions: b if (stopAtCallExpressions) { return node; } - // falls through + // falls through case SyntaxKind.AsExpression: case SyntaxKind.ElementAccessExpression: case SyntaxKind.PropertyAccessExpression: @@ -9333,7 +9341,7 @@ export function compilerOptionsAffectDeclarationPath(newOptions: CompilerOptions export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown { return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : option.allowJsFlag ? getAllowJSCompilerOption(options) : - options[option.name]; + options[option.name]; } /** @internal */ @@ -9352,10 +9360,10 @@ export function getJSXImplicitImportBase(compilerOptions: CompilerOptions, file? return undefined; } return compilerOptions.jsx === JsxEmit.ReactJSX || - compilerOptions.jsx === JsxEmit.ReactJSXDev || - compilerOptions.jsxImportSource || - jsxImportSourcePragma || - jsxRuntimePragma?.arguments.factory === "automatic" ? + compilerOptions.jsx === JsxEmit.ReactJSXDev || + compilerOptions.jsxImportSource || + jsxImportSourcePragma || + jsxRuntimePragma?.arguments.factory === "automatic" ? jsxImportSourcePragma?.arguments.factory || compilerOptions.jsxImportSource || "react" : undefined; } @@ -10028,7 +10036,7 @@ export function getModuleSpecifierEndingPreference(preference: UserPreferences[" let usesJsExtensions = false; const specifiers = sourceFile?.imports.length ? sourceFile.imports : sourceFile && isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0]) : - emptyArray; + emptyArray; for (const specifier of specifiers) { if (pathIsRelative(specifier.text)) { if ( @@ -10431,7 +10439,7 @@ export function parsePseudoBigInt(stringValue: string): string { const digit = digitChar <= CharacterCodes._9 ? digitChar - CharacterCodes._0 : 10 + digitChar - - (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); + (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); const shiftedDigit = digit << (bitOffset & 15); segments[segment] |= shiftedDigit; const residual = shiftedDigit >>> 16; @@ -10786,7 +10794,7 @@ export function getContainingNodeArray(node: Node): NodeArray | undefined case SyntaxKind.NewExpression: return isTypeNode(node) ? (parent as CallExpression | NewExpression).typeArguments : (parent as CallExpression | NewExpression).expression === node ? undefined : - (parent as CallExpression | NewExpression).arguments; + (parent as CallExpression | NewExpression).arguments; case SyntaxKind.JsxElement: case SyntaxKind.JsxFragment: return isJsxChild(node) ? (parent as JsxElement | JsxFragment).children : undefined; @@ -10881,7 +10889,7 @@ export function createPropertyNameNodeForIdentifierOrLiteral(name: string, targe const isMethodNamedNew = isMethod && name === "new"; return !isMethodNamedNew && isIdentifierText(name, target) ? factory.createIdentifier(name) : !stringNamed && !isMethodNamedNew && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : - factory.createStringLiteral(name, !!singleQuote); + factory.createStringLiteral(name, !!singleQuote); } /** @internal */ @@ -11487,11 +11495,11 @@ export function createNameResolver({ useResult = result.flags & SymbolFlags.TypeParameter // type parameters are visible in parameter list, return type and type parameter list ? !!(lastLocation.flags & NodeFlags.Synthesized) || // Synthetic fake scopes are added for signatures so type parameters are accessible from them - lastLocation === (location as FunctionLikeDeclaration).type || - lastLocation.kind === SyntaxKind.Parameter || - lastLocation.kind === SyntaxKind.JSDocParameterTag || - lastLocation.kind === SyntaxKind.JSDocReturnTag || - lastLocation.kind === SyntaxKind.TypeParameter + lastLocation === (location as FunctionLikeDeclaration).type || + lastLocation.kind === SyntaxKind.Parameter || + lastLocation.kind === SyntaxKind.JSDocParameterTag || + lastLocation.kind === SyntaxKind.JSDocReturnTag || + lastLocation.kind === SyntaxKind.TypeParameter // local types not visible outside the function body : false; } @@ -11532,7 +11540,7 @@ export function createNameResolver({ switch (location.kind) { case SyntaxKind.SourceFile: if (!isExternalOrCommonJsModule(location as SourceFile)) break; - // falls through + // falls through case SyntaxKind.ModuleDeclaration: const moduleExports = getSymbolOfDeclaration(location as SourceFile | ModuleDeclaration)?.exports || emptySymbols; if (location.kind === SyntaxKind.SourceFile || (isModuleDeclaration(location) && location.flags & NodeFlags.Ambient && !isGlobalScopeAugmentation(location))) { @@ -11678,7 +11686,7 @@ export function createNameResolver({ if (getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015) { break; } - // falls through + // falls through case SyntaxKind.MethodDeclaration: case SyntaxKind.Constructor: case SyntaxKind.GetAccessor: @@ -11792,7 +11800,7 @@ export function createNameResolver({ lastLocation = location; location = isJSDocTemplateTag(location) ? getEffectiveContainerForJSDocTemplateTag(location) || location.parent : isJSDocParameterTag(location) || isJSDocReturnTag(location) ? getHostSignatureFromJSDoc(location) || location.parent : - location.parent; + location.parent; } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. @@ -12289,7 +12297,7 @@ function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (n // This only happens for leaf nodes - internal nodes always see their children change. const clone = isStringLiteral(node) ? setOriginalNode(factory.createStringLiteralFromNode(node), node) as Node as T : isNumericLiteral(node) ? setOriginalNode(factory.createNumericLiteral(node.text, node.numericLiteralFlags), node) as Node as T : - factory.cloneNode(node); + factory.cloneNode(node); return setTextRange(clone, node); } diff --git a/tests/baselines/reference/enumKeysInTypeLiteral.js b/tests/baselines/reference/enumKeysInTypeLiteral.js new file mode 100644 index 0000000000000..5ced5711974d4 --- /dev/null +++ b/tests/baselines/reference/enumKeysInTypeLiteral.js @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] //// + +//// [enumKeysInTypeLiteral.ts] +enum Type { + Foo = 'foo', + '3x14' = '3x14' +} + +type TypeMap = { + [Type.Foo]: 1; + [Type['3x14']]: 2; +} + +const t: TypeMap = { + 'foo': 1, + '3x14': 2 +}; + +enum Numeric { + Negative = -1, + Zero = 0 +} + +type NumericMap = { + // Valid: Accessing enum member via string literal for the name + [Numeric['Negative']]: number; + [Numeric['Zero']]: number; + // Valid: Parenthesized access + [Numeric[('Negative')]]: number; +} + + + +//// [enumKeysInTypeLiteral.js] +var Type; +(function (Type) { + Type["Foo"] = "foo"; + Type["3x14"] = "3x14"; +})(Type || (Type = {})); +var t = { + 'foo': 1, + '3x14': 2 +}; +var Numeric; +(function (Numeric) { + Numeric[Numeric["Negative"] = -1] = "Negative"; + Numeric[Numeric["Zero"] = 0] = "Zero"; +})(Numeric || (Numeric = {})); diff --git a/tests/baselines/reference/enumKeysInTypeLiteral.symbols b/tests/baselines/reference/enumKeysInTypeLiteral.symbols new file mode 100644 index 0000000000000..7585e72aea178 --- /dev/null +++ b/tests/baselines/reference/enumKeysInTypeLiteral.symbols @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] //// + +=== enumKeysInTypeLiteral.ts === +enum Type { +>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0)) + + Foo = 'foo', +>Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11)) + + '3x14' = '3x14' +>'3x14' : Symbol(Type['3x14'], Decl(enumKeysInTypeLiteral.ts, 1, 14)) +} + +type TypeMap = { +>TypeMap : Symbol(TypeMap, Decl(enumKeysInTypeLiteral.ts, 3, 1)) + + [Type.Foo]: 1; +>[Type.Foo] : Symbol([Type.Foo], Decl(enumKeysInTypeLiteral.ts, 5, 16)) +>Type.Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11)) +>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0)) +>Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11)) + + [Type['3x14']]: 2; +>[Type['3x14']] : Symbol([Type['3x14']], Decl(enumKeysInTypeLiteral.ts, 6, 16)) +>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0)) +>'3x14' : Symbol(Type['3x14'], Decl(enumKeysInTypeLiteral.ts, 1, 14)) +} + +const t: TypeMap = { +>t : Symbol(t, Decl(enumKeysInTypeLiteral.ts, 10, 5)) +>TypeMap : Symbol(TypeMap, Decl(enumKeysInTypeLiteral.ts, 3, 1)) + + 'foo': 1, +>'foo' : Symbol('foo', Decl(enumKeysInTypeLiteral.ts, 10, 20)) + + '3x14': 2 +>'3x14' : Symbol('3x14', Decl(enumKeysInTypeLiteral.ts, 11, 13)) + +}; + +enum Numeric { +>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2)) + + Negative = -1, +>Negative : Symbol(Numeric.Negative, Decl(enumKeysInTypeLiteral.ts, 15, 14)) + + Zero = 0 +>Zero : Symbol(Numeric.Zero, Decl(enumKeysInTypeLiteral.ts, 16, 18)) +} + +type NumericMap = { +>NumericMap : Symbol(NumericMap, Decl(enumKeysInTypeLiteral.ts, 18, 1)) + + // Valid: Accessing enum member via string literal for the name + [Numeric['Negative']]: number; +>[Numeric['Negative']] : Symbol([Numeric['Negative']], Decl(enumKeysInTypeLiteral.ts, 20, 19), Decl(enumKeysInTypeLiteral.ts, 23, 30)) +>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2)) +>'Negative' : Symbol(Numeric.Negative, Decl(enumKeysInTypeLiteral.ts, 15, 14)) + + [Numeric['Zero']]: number; +>[Numeric['Zero']] : Symbol([Numeric['Zero']], Decl(enumKeysInTypeLiteral.ts, 22, 34)) +>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2)) +>'Zero' : Symbol(Numeric.Zero, Decl(enumKeysInTypeLiteral.ts, 16, 18)) + + // Valid: Parenthesized access + [Numeric[('Negative')]]: number; +>[Numeric[('Negative')]] : Symbol([Numeric['Negative']], Decl(enumKeysInTypeLiteral.ts, 20, 19), Decl(enumKeysInTypeLiteral.ts, 23, 30)) +>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2)) +} + + diff --git a/tests/baselines/reference/enumKeysInTypeLiteral.types b/tests/baselines/reference/enumKeysInTypeLiteral.types new file mode 100644 index 0000000000000..4dee1182693b4 --- /dev/null +++ b/tests/baselines/reference/enumKeysInTypeLiteral.types @@ -0,0 +1,124 @@ +//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] //// + +=== enumKeysInTypeLiteral.ts === +enum Type { +>Type : Type +> : ^^^^ + + Foo = 'foo', +>Foo : Type.Foo +> : ^^^^^^^^ +>'foo' : "foo" +> : ^^^^^ + + '3x14' = '3x14' +>'3x14' : (typeof Type)["3x14"] +> : ^^^^^^^^^^^^^^^^^^^^^ +>'3x14' : "3x14" +> : ^^^^^^ +} + +type TypeMap = { +>TypeMap : TypeMap +> : ^^^^^^^ + + [Type.Foo]: 1; +>[Type.Foo] : 1 +> : ^ +>Type.Foo : Type.Foo +> : ^^^^^^^^ +>Type : typeof Type +> : ^^^^^^^^^^^ +>Foo : Type.Foo +> : ^^^^^^^^ + + [Type['3x14']]: 2; +>[Type['3x14']] : 2 +> : ^ +>Type['3x14'] : (typeof Type)["3x14"] +> : ^^^^^^^^^^^^^^^^^^^^^ +>Type : typeof Type +> : ^^^^^^^^^^^ +>'3x14' : "3x14" +> : ^^^^^^ +} + +const t: TypeMap = { +>t : TypeMap +> : ^^^^^^^ +>{ 'foo': 1, '3x14': 2} : { foo: 1; '3x14': 2; } +> : ^^^^^^^^^^^^^^^^^^^^^^ + + 'foo': 1, +>'foo' : 1 +> : ^ +>1 : 1 +> : ^ + + '3x14': 2 +>'3x14' : 2 +> : ^ +>2 : 2 +> : ^ + +}; + +enum Numeric { +>Numeric : Numeric +> : ^^^^^^^ + + Negative = -1, +>Negative : Numeric.Negative +> : ^^^^^^^^^^^^^^^^ +>-1 : -1 +> : ^^ +>1 : 1 +> : ^ + + Zero = 0 +>Zero : Numeric.Zero +> : ^^^^^^^^^^^^ +>0 : 0 +> : ^ +} + +type NumericMap = { +>NumericMap : NumericMap +> : ^^^^^^^^^^ + + // Valid: Accessing enum member via string literal for the name + [Numeric['Negative']]: number; +>[Numeric['Negative']] : number +> : ^^^^^^ +>Numeric['Negative'] : Numeric.Negative +> : ^^^^^^^^^^^^^^^^ +>Numeric : typeof Numeric +> : ^^^^^^^^^^^^^^ +>'Negative' : "Negative" +> : ^^^^^^^^^^ + + [Numeric['Zero']]: number; +>[Numeric['Zero']] : number +> : ^^^^^^ +>Numeric['Zero'] : Numeric.Zero +> : ^^^^^^^^^^^^ +>Numeric : typeof Numeric +> : ^^^^^^^^^^^^^^ +>'Zero' : "Zero" +> : ^^^^^^ + + // Valid: Parenthesized access + [Numeric[('Negative')]]: number; +>[Numeric[('Negative')]] : number +> : ^^^^^^ +>Numeric[('Negative')] : Numeric.Negative +> : ^^^^^^^^^^^^^^^^ +>Numeric : typeof Numeric +> : ^^^^^^^^^^^^^^ +>('Negative') : "Negative" +> : ^^^^^^^^^^ +>'Negative' : "Negative" +> : ^^^^^^^^^^ +} + + diff --git a/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt b/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt index 812ec2c1bea83..6931ab5f5df2b 100644 --- a/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt +++ b/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt @@ -1,6 +1,6 @@ isolatedDeclarationLazySymbols.ts(1,17): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations. +isolatedDeclarationLazySymbols.ts(12,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. isolatedDeclarationLazySymbols.ts(13,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. -isolatedDeclarationLazySymbols.ts(16,5): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. isolatedDeclarationLazySymbols.ts(16,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. isolatedDeclarationLazySymbols.ts(21,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. @@ -22,6 +22,8 @@ isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names o } as const foo[o["prop.inner"]] ="A"; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. foo[o.prop.inner] = "B"; ~~~~~~~~~~~~~~~~~ !!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. @@ -29,8 +31,6 @@ isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names o export class Foo { [o["prop.inner"]] ="A" ~~~~~~~~~~~~~~~~~ -!!! error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type. - ~~~~~~~~~~~~~~~~~ !!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. [o.prop.inner] = "B" } diff --git a/tests/baselines/reference/isolatedDeclarationLazySymbols.types b/tests/baselines/reference/isolatedDeclarationLazySymbols.types index c7e91f9680a8c..5a1bfe22638bd 100644 --- a/tests/baselines/reference/isolatedDeclarationLazySymbols.types +++ b/tests/baselines/reference/isolatedDeclarationLazySymbols.types @@ -40,8 +40,8 @@ const o = { foo[o["prop.inner"]] ="A"; >foo[o["prop.inner"]] ="A" : "A" > : ^^^ ->foo[o["prop.inner"]] : any -> : ^^^ +>foo[o["prop.inner"]] : string +> : ^^^^^^ >foo : typeof foo > : ^^^^^^^^^^ >o["prop.inner"] : "a" From 415baaab21f350e778b28d5be1c1b7121569dd62 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Thu, 5 Feb 2026 22:17:38 +0100 Subject: [PATCH 3/3] fix: correct isLateBindableAST to pass entire ElementAccessExpression Fixes the bug identified by Copilot AI review where isLateBindableAST was incorrectly passing only node.argumentExpression instead of the entire node to isLateBindableExpression. This ensures proper validation of the full element access chain. The fix makes the behavior more strict: only syntactic literals are accepted in element access expressions (e.g., Type['3x14']), not variables with literal types (e.g., Type[variable]). --- src/compiler/checker.ts | 2 +- src/compiler/utilities.ts | 174 +++++++++--------- ...arationEmitLateBoundAssignments.errors.txt | 58 ++++++ .../declarationEmitLateBoundAssignments.js | 1 - .../declarationEmitLateBoundAssignments.types | 32 ++-- ...rationEmitLateBoundAssignments2.errors.txt | 121 ++++++++++++ .../declarationEmitLateBoundAssignments2.js | 32 +--- ...declarationEmitLateBoundAssignments2.types | 100 +++++----- ...ationEmitLateBoundJSAssignments.errors.txt | 63 +++++++ .../declarationEmitLateBoundJSAssignments.js | 1 - ...eclarationEmitLateBoundJSAssignments.types | 32 ++-- ...ionExpressionsWithDynamicNames2.errors.txt | 26 +++ ...FunctionExpressionsWithDynamicNames2.types | 8 +- .../expandoFunctionSymbolProperty.errors.txt | 27 +++ .../expandoFunctionSymbolProperty.types | 16 +- ...expandoFunctionSymbolPropertyJs.errors.txt | 30 +++ .../expandoFunctionSymbolPropertyJs.types | 16 +- .../isolatedDeclarationLazySymbols.errors.txt | 8 +- .../isolatedDeclarationLazySymbols.types | 8 +- .../lateBoundAssignmentCandidateJS3.symbols | 2 +- ...ndAssignmentDeclarationSupport7.errors.txt | 37 ++++ ...BoundAssignmentDeclarationSupport7.symbols | 1 - ...teBoundAssignmentDeclarationSupport7.types | 25 +-- ...ateBoundClassMemberAssignmentJS.errors.txt | 29 +++ .../lateBoundClassMemberAssignmentJS.js | 3 - .../lateBoundClassMemberAssignmentJS.types | 16 +- ...teBoundClassMemberAssignmentJS2.errors.txt | 29 +++ .../lateBoundClassMemberAssignmentJS2.js | 1 - .../lateBoundClassMemberAssignmentJS2.types | 16 +- ...teBoundClassMemberAssignmentJS3.errors.txt | 32 ++++ .../lateBoundClassMemberAssignmentJS3.js | 3 - .../lateBoundClassMemberAssignmentJS3.types | 16 +- ...ionMemberAssignmentDeclarations.errors.txt | 20 ++ ...FunctionMemberAssignmentDeclarations.types | 8 +- .../lateBoundMethodNameAssigmentJS.js | 2 +- .../reference/wellKnownSymbolExpando.types | 2 +- 36 files changed, 716 insertions(+), 281 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitLateBoundAssignments.errors.txt create mode 100644 tests/baselines/reference/declarationEmitLateBoundAssignments2.errors.txt create mode 100644 tests/baselines/reference/declarationEmitLateBoundJSAssignments.errors.txt create mode 100644 tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.errors.txt create mode 100644 tests/baselines/reference/expandoFunctionSymbolProperty.errors.txt create mode 100644 tests/baselines/reference/expandoFunctionSymbolPropertyJs.errors.txt create mode 100644 tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.errors.txt create mode 100644 tests/baselines/reference/lateBoundClassMemberAssignmentJS.errors.txt create mode 100644 tests/baselines/reference/lateBoundClassMemberAssignmentJS2.errors.txt create mode 100644 tests/baselines/reference/lateBoundClassMemberAssignmentJS3.errors.txt create mode 100644 tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba991df874f62..6a9e4b7cae5bb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13752,7 +13752,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isLateBindableExpression(node.expression); } else if (isElementAccessExpression(node)) { - return isLateBindableExpression(node.argumentExpression); + return isLateBindableExpression(node); } return false; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 469e8965b4d02..fb379a8078c6c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -811,13 +811,13 @@ export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleWithFaile return oldResolution === newResolution || oldResolution.resolvedModule === newResolution.resolvedModule || !!oldResolution.resolvedModule && - !!newResolution.resolvedModule && - oldResolution.resolvedModule.isExternalLibraryImport === newResolution.resolvedModule.isExternalLibraryImport && - oldResolution.resolvedModule.extension === newResolution.resolvedModule.extension && - oldResolution.resolvedModule.resolvedFileName === newResolution.resolvedModule.resolvedFileName && - oldResolution.resolvedModule.originalPath === newResolution.resolvedModule.originalPath && - packageIdIsEqual(oldResolution.resolvedModule.packageId, newResolution.resolvedModule.packageId) && - oldResolution.alternateResult === newResolution.alternateResult; + !!newResolution.resolvedModule && + oldResolution.resolvedModule.isExternalLibraryImport === newResolution.resolvedModule.isExternalLibraryImport && + oldResolution.resolvedModule.extension === newResolution.resolvedModule.extension && + oldResolution.resolvedModule.resolvedFileName === newResolution.resolvedModule.resolvedFileName && + oldResolution.resolvedModule.originalPath === newResolution.resolvedModule.originalPath && + packageIdIsEqual(oldResolution.resolvedModule.packageId, newResolution.resolvedModule.packageId) && + oldResolution.alternateResult === newResolution.alternateResult; } /** @internal */ @@ -846,25 +846,25 @@ export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeChec ...alternateResultMessage[1], ) : host.typesPackageExists(packageName) - ? chainDiagnosticMessages( + ? chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, - packageName, - mangleScopedPackageName(packageName), - ) - : host.packageBundlesTypes(packageName) - ? chainDiagnosticMessages( + Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, + packageName, + mangleScopedPackageName(packageName), + ) + : host.packageBundlesTypes(packageName) + ? chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, - packageName, - moduleReference, - ) - : chainDiagnosticMessages( + Diagnostics.If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1, + packageName, + moduleReference, + ) + : chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, - moduleReference, - mangleScopedPackageName(packageName), - ); + Diagnostics.Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, + moduleReference, + mangleScopedPackageName(packageName), + ); if (result) result.repopulateInfo = () => ({ moduleReference, mode, packageName: packageName === moduleReference ? undefined : packageName }); return result; } @@ -888,15 +888,15 @@ export function createModeMismatchDetails(currentSourceFile: SourceFile): Diagno combinePaths(scope.packageDirectory, "package.json"), ) : targetExt ? - chainDiagnosticMessages( + chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_package_json_file_with_type_Colon_module, - targetExt, - ) : - chainDiagnosticMessages( + Diagnostics.To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_package_json_file_with_type_Colon_module, + targetExt, + ) : + chainDiagnosticMessages( /*details*/ undefined, - Diagnostics.To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module, - ); + Diagnostics.To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module, + ); result.repopulateInfo = () => true; return result; } @@ -920,10 +920,10 @@ export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirec return oldResolution === newResolution || oldResolution.resolvedTypeReferenceDirective === newResolution.resolvedTypeReferenceDirective || !!oldResolution.resolvedTypeReferenceDirective && - !!newResolution.resolvedTypeReferenceDirective && - oldResolution.resolvedTypeReferenceDirective.resolvedFileName === newResolution.resolvedTypeReferenceDirective.resolvedFileName && - !!oldResolution.resolvedTypeReferenceDirective.primary === !!newResolution.resolvedTypeReferenceDirective.primary && - oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; + !!newResolution.resolvedTypeReferenceDirective && + oldResolution.resolvedTypeReferenceDirective.resolvedFileName === newResolution.resolvedTypeReferenceDirective.resolvedFileName && + !!oldResolution.resolvedTypeReferenceDirective.primary === !!newResolution.resolvedTypeReferenceDirective.primary && + oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; } /** @internal */ @@ -1189,11 +1189,11 @@ export function isRecognizedTripleSlashComment(text: string, commentPos: number, ) { const textSubStr = text.substring(commentPos, commentEnd); return fullTripleSlashReferencePathRegEx.test(textSubStr) || - fullTripleSlashAMDReferencePathRegEx.test(textSubStr) || - fullTripleSlashAMDModuleRegEx.test(textSubStr) || - fullTripleSlashReferenceTypeReferenceDirectiveRegEx.test(textSubStr) || - fullTripleSlashLibReferenceRegEx.test(textSubStr) || - defaultLibReferenceRegEx.test(textSubStr) ? + fullTripleSlashAMDReferencePathRegEx.test(textSubStr) || + fullTripleSlashAMDModuleRegEx.test(textSubStr) || + fullTripleSlashReferenceTypeReferenceDirectiveRegEx.test(textSubStr) || + fullTripleSlashLibReferenceRegEx.test(textSubStr) || + defaultLibReferenceRegEx.test(textSubStr) ? true : false; } return false; @@ -1943,7 +1943,7 @@ export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | u case SyntaxKind.StringLiteral: { const escapeText = flags & GetLiteralTextFlags.JsxAttributeEscape ? escapeJsxAttributeString : flags & GetLiteralTextFlags.NeverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : - escapeNonAsciiString; + escapeNonAsciiString; if ((node as StringLiteral).singleQuote) { return "'" + escapeText(node.text, CharacterCodes.singleQuote) + "'"; } @@ -2723,12 +2723,12 @@ export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: Sour /** @internal */ export function getJSDocCommentRanges(node: Node, text: string): CommentRange[] | undefined { const commentRanges = (node.kind === SyntaxKind.Parameter || - node.kind === SyntaxKind.TypeParameter || - node.kind === SyntaxKind.FunctionExpression || - node.kind === SyntaxKind.ArrowFunction || - node.kind === SyntaxKind.ParenthesizedExpression || - node.kind === SyntaxKind.VariableDeclaration || - node.kind === SyntaxKind.ExportSpecifier) ? + node.kind === SyntaxKind.TypeParameter || + node.kind === SyntaxKind.FunctionExpression || + node.kind === SyntaxKind.ArrowFunction || + node.kind === SyntaxKind.ParenthesizedExpression || + node.kind === SyntaxKind.VariableDeclaration || + node.kind === SyntaxKind.ExportSpecifier) ? concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) : getLeadingCommentRanges(text, node.pos); // True if the comment starts with '/**' but not if it is '/**/' @@ -2994,7 +2994,7 @@ export function isCommonJsExportPropertyAssignment(node: Node): boolean { export function isValidESSymbolDeclaration(node: Node): boolean { return (isVariableDeclaration(node) ? isVarConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : isPropertyDeclaration(node) ? hasEffectiveReadonlyModifier(node) && hasStaticModifier(node) : - isPropertySignature(node) && hasEffectiveReadonlyModifier(node)) || isCommonJsExportPropertyAssignment(node); + isPropertySignature(node) && hasEffectiveReadonlyModifier(node)) || isCommonJsExportPropertyAssignment(node); } /** @internal */ @@ -3540,7 +3540,7 @@ export function classElementOrClassElementParameterIsDecorated(useLegacyDecorato const { firstAccessor, secondAccessor, setAccessor } = getAllAccessorDeclarations(parent.members, node); const firstAccessorWithDecorators = hasDecorators(firstAccessor) ? firstAccessor : secondAccessor && hasDecorators(secondAccessor) ? secondAccessor : - undefined; + undefined; if (!firstAccessorWithDecorators || node !== firstAccessorWithDecorators) { return false; } @@ -3990,7 +3990,7 @@ function getDefaultedExpandoInitializer(name: Expression, initializer: Expressio export function isDefaultedExpandoInitializer(node: BinaryExpression): boolean | undefined { const name = isVariableDeclaration(node.parent) ? node.parent.name : isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken ? node.parent.left : - undefined; + undefined; return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left); } @@ -4030,9 +4030,9 @@ export function isSameEntityName(name: Expression, initializer: Expression): boo isMemberName(name) && isLiteralLikeAccess(initializer) && (initializer.expression.kind === SyntaxKind.ThisKeyword || isIdentifier(initializer.expression) && - (initializer.expression.escapedText === "window" || - initializer.expression.escapedText === "self" || - initializer.expression.escapedText === "global")) + (initializer.expression.escapedText === "window" || + initializer.expression.escapedText === "self" || + initializer.expression.escapedText === "global")) ) { return isSameEntityName(name, getNameOrArgument(initializer)); } @@ -4270,7 +4270,7 @@ export function setValueDeclaration(symbol: Symbol, node: Declaration): void { if ( !valueDeclaration || !(node.flags & NodeFlags.Ambient && !isInJSFile(node) && !(valueDeclaration.flags & NodeFlags.Ambient)) && - (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || + (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration)) ) { // other kinds of value declarations take precedence over modules and assignment declarations @@ -4451,18 +4451,18 @@ export function isTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallback function getSourceOfAssignment(node: Node): Node | undefined { return isExpressionStatement(node) && - isBinaryExpression(node.expression) && - node.expression.operatorToken.kind === SyntaxKind.EqualsToken + isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === SyntaxKind.EqualsToken ? getRightMostAssignedExpression(node.expression) : undefined; } function getSourceOfDefaultedAssignment(node: Node): Node | undefined { return isExpressionStatement(node) && - isBinaryExpression(node.expression) && - getAssignmentDeclarationKind(node.expression) !== AssignmentDeclarationKind.None && - isBinaryExpression(node.expression.right) && - (node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken || node.expression.right.operatorToken.kind === SyntaxKind.QuestionQuestionToken) + isBinaryExpression(node.expression) && + getAssignmentDeclarationKind(node.expression) !== AssignmentDeclarationKind.None && + isBinaryExpression(node.expression.right) && + (node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken || node.expression.right.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? node.expression.right.right : undefined; } @@ -4486,8 +4486,8 @@ export function getSingleVariableOfVariableStatement(node: Node): VariableDeclar function getNestedModuleDeclaration(node: Node): Node | undefined { return isModuleDeclaration(node) && - node.body && - node.body.kind === SyntaxKind.ModuleDeclaration + node.body && + node.body.kind === SyntaxKind.ModuleDeclaration ? node.body : undefined; } @@ -5056,9 +5056,9 @@ export function getDeclarationFromName(name: Node): Declaration | undefined { else { const binExp = parent.parent; return isBinaryExpression(binExp) && - getAssignmentDeclarationKind(binExp) !== AssignmentDeclarationKind.None && - ((binExp.left as BindableStaticNameExpression).symbol || binExp.symbol) && - getNameOfDeclaration(binExp) === name + getAssignmentDeclarationKind(binExp) !== AssignmentDeclarationKind.None && + ((binExp.left as BindableStaticNameExpression).symbol || binExp.symbol) && + getNameOfDeclaration(binExp) === name ? binExp : undefined; } @@ -5190,7 +5190,7 @@ export function getEffectiveImplementsTypeNodes(node: ClassLikeDeclaration): und export function getAllSuperTypeNodes(node: Node): readonly TypeNode[] { return isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || emptyArray : isClassLike(node) ? concatenate(singleElementArray(getEffectiveBaseTypeNode(node)), getEffectiveImplementsTypeNodes(node)) || emptyArray : - emptyArray; + emptyArray; } /** @internal */ @@ -6168,7 +6168,7 @@ function getReplacement(c: string, offset: number, input: string) { export function escapeString(s: string, quoteChar?: CharacterCodes.doubleQuote | CharacterCodes.singleQuote | CharacterCodes.backtick): string { const escapedCharsRegExp = quoteChar === CharacterCodes.backtick ? backtickQuoteEscapedCharsRegExp : quoteChar === CharacterCodes.singleQuote ? singleQuoteEscapedCharsRegExp : - doubleQuoteEscapedCharsRegExp; + doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement); } @@ -6531,8 +6531,8 @@ export function getDeclarationEmitOutputFilePathWorker(fileName: string, options export function getDeclarationEmitExtensionForPath(path: string): Extension.Dts | Extension.Dmts | Extension.Dcts | ".d.json.ts" { return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : - fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well - Extension.Dts; + fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well + Extension.Dts; } /** @@ -6543,8 +6543,8 @@ export function getDeclarationEmitExtensionForPath(path: string): Extension.Dts export function getPossibleOriginalInputExtensionForExtension(path: string): Extension[] { return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] : fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs] : - fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : - [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; + fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : + [Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js]; } /** @internal */ @@ -8015,7 +8015,7 @@ export function getDeclarationModifierFlagsFromSymbol(s: Symbol, isWrite = false const checkFlags = (s as TransientSymbol).links.checkFlags; const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private : checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public : - ModifierFlags.Protected; + ModifierFlags.Protected; const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0; return accessModifier | staticModifier; } @@ -9360,7 +9360,7 @@ export function compilerOptionsAffectDeclarationPath(newOptions: CompilerOptions export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown { return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : option.allowJsFlag ? getAllowJSCompilerOption(options) : - options[option.name]; + options[option.name]; } /** @internal */ @@ -9379,10 +9379,10 @@ export function getJSXImplicitImportBase(compilerOptions: CompilerOptions, file? return undefined; } return compilerOptions.jsx === JsxEmit.ReactJSX || - compilerOptions.jsx === JsxEmit.ReactJSXDev || - compilerOptions.jsxImportSource || - jsxImportSourcePragma || - jsxRuntimePragma?.arguments.factory === "automatic" ? + compilerOptions.jsx === JsxEmit.ReactJSXDev || + compilerOptions.jsxImportSource || + jsxImportSourcePragma || + jsxRuntimePragma?.arguments.factory === "automatic" ? jsxImportSourcePragma?.arguments.factory || compilerOptions.jsxImportSource || "react" : undefined; } @@ -10055,7 +10055,7 @@ export function getModuleSpecifierEndingPreference(preference: UserPreferences[" let usesJsExtensions = false; const specifiers = sourceFile?.imports.length ? sourceFile.imports : sourceFile && isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0]) : - emptyArray; + emptyArray; for (const specifier of specifiers) { if (pathIsRelative(specifier.text)) { if ( @@ -10458,7 +10458,7 @@ export function parsePseudoBigInt(stringValue: string): string { const digit = digitChar <= CharacterCodes._9 ? digitChar - CharacterCodes._0 : 10 + digitChar - - (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); + (digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a); const shiftedDigit = digit << (bitOffset & 15); segments[segment] |= shiftedDigit; const residual = shiftedDigit >>> 16; @@ -10813,7 +10813,7 @@ export function getContainingNodeArray(node: Node): NodeArray | undefined case SyntaxKind.NewExpression: return isTypeNode(node) ? (parent as CallExpression | NewExpression).typeArguments : (parent as CallExpression | NewExpression).expression === node ? undefined : - (parent as CallExpression | NewExpression).arguments; + (parent as CallExpression | NewExpression).arguments; case SyntaxKind.JsxElement: case SyntaxKind.JsxFragment: return isJsxChild(node) ? (parent as JsxElement | JsxFragment).children : undefined; @@ -10908,7 +10908,7 @@ export function createPropertyNameNodeForIdentifierOrLiteral(name: string, targe const isMethodNamedNew = isMethod && name === "new"; return !isMethodNamedNew && isIdentifierText(name, target) ? factory.createIdentifier(name) : !stringNamed && !isMethodNamedNew && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : - factory.createStringLiteral(name, !!singleQuote); + factory.createStringLiteral(name, !!singleQuote); } /** @internal */ @@ -11514,11 +11514,11 @@ export function createNameResolver({ useResult = result.flags & SymbolFlags.TypeParameter // type parameters are visible in parameter list, return type and type parameter list ? !!(lastLocation.flags & NodeFlags.Synthesized) || // Synthetic fake scopes are added for signatures so type parameters are accessible from them - lastLocation === (location as FunctionLikeDeclaration).type || - lastLocation.kind === SyntaxKind.Parameter || - lastLocation.kind === SyntaxKind.JSDocParameterTag || - lastLocation.kind === SyntaxKind.JSDocReturnTag || - lastLocation.kind === SyntaxKind.TypeParameter + lastLocation === (location as FunctionLikeDeclaration).type || + lastLocation.kind === SyntaxKind.Parameter || + lastLocation.kind === SyntaxKind.JSDocParameterTag || + lastLocation.kind === SyntaxKind.JSDocReturnTag || + lastLocation.kind === SyntaxKind.TypeParameter // local types not visible outside the function body : false; } @@ -11819,7 +11819,7 @@ export function createNameResolver({ lastLocation = location; location = isJSDocTemplateTag(location) ? getEffectiveContainerForJSDocTemplateTag(location) || location.parent : isJSDocParameterTag(location) || isJSDocReturnTag(location) ? getHostSignatureFromJSDoc(location) || location.parent : - location.parent; + location.parent; } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. @@ -12316,7 +12316,7 @@ function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (n // This only happens for leaf nodes - internal nodes always see their children change. const clone = isStringLiteral(node) ? setOriginalNode(factory.createStringLiteralFromNode(node), node) as Node as T : isNumericLiteral(node) ? setOriginalNode(factory.createNumericLiteral(node.text, node.numericLiteralFlags), node) as Node as T : - factory.cloneNode(node); + factory.cloneNode(node); return setTextRange(clone, node); } diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments.errors.txt b/tests/baselines/reference/declarationEmitLateBoundAssignments.errors.txt new file mode 100644 index 0000000000000..3a2c256bfbc25 --- /dev/null +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments.errors.txt @@ -0,0 +1,58 @@ +declarationEmitLateBoundAssignments.ts(4,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(6,1): error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. + Property 'strMemName' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(8,1): error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. + Property 'dashed-str-mem' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(10,1): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. + Property '42' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(12,19): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(13,19): error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. + Property 'strMemName' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(14,19): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. + Property '42' does not exist on type 'typeof foo'. +declarationEmitLateBoundAssignments.ts(15,19): error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. + Property 'dashed-str-mem' does not exist on type 'typeof foo'. + + +==== declarationEmitLateBoundAssignments.ts (8 errors) ==== + export function foo() {} + foo.bar = 12; + const _private = Symbol(); + foo[_private] = "ok"; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + const strMem = "strMemName"; + foo[strMem] = "ok"; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'strMemName' does not exist on type 'typeof foo'. + const dashStrMem = "dashed-str-mem"; + foo[dashStrMem] = "ok"; + ~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'dashed-str-mem' does not exist on type 'typeof foo'. + const numMem = 42; + foo[numMem] = "ok"; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '42' does not exist on type 'typeof foo'. + + const x: string = foo[_private]; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + const y: string = foo[strMem]; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'strMemName' does not exist on type 'typeof foo'. + const z: string = foo[numMem]; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '42' does not exist on type 'typeof foo'. + const a: string = foo[dashStrMem]; + ~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'dashed-str-mem' does not exist on type 'typeof foo'. \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments.js b/tests/baselines/reference/declarationEmitLateBoundAssignments.js index b76db45754c89..763511ec0da42 100644 --- a/tests/baselines/reference/declarationEmitLateBoundAssignments.js +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments.js @@ -38,5 +38,4 @@ const a = foo[dashStrMem]; export declare function foo(): void; export declare namespace foo { var bar: number; - var strMemName: string; } diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments.types b/tests/baselines/reference/declarationEmitLateBoundAssignments.types index b0e1eedca1774..27333f048ef82 100644 --- a/tests/baselines/reference/declarationEmitLateBoundAssignments.types +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments.types @@ -28,8 +28,8 @@ const _private = Symbol(); foo[_private] = "ok"; >foo[_private] = "ok" : "ok" > : ^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol @@ -46,8 +46,8 @@ const strMem = "strMemName"; foo[strMem] = "ok"; >foo[strMem] = "ok" : "ok" > : ^^^^ ->foo[strMem] : string -> : ^^^^^^ +>foo[strMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >strMem : "strMemName" @@ -64,8 +64,8 @@ const dashStrMem = "dashed-str-mem"; foo[dashStrMem] = "ok"; >foo[dashStrMem] = "ok" : "ok" > : ^^^^ ->foo[dashStrMem] : string -> : ^^^^^^ +>foo[dashStrMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >dashStrMem : "dashed-str-mem" @@ -82,8 +82,8 @@ const numMem = 42; foo[numMem] = "ok"; >foo[numMem] = "ok" : "ok" > : ^^^^ ->foo[numMem] : string -> : ^^^^^^ +>foo[numMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >numMem : 42 @@ -94,8 +94,8 @@ foo[numMem] = "ok"; const x: string = foo[_private]; >x : string > : ^^^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol @@ -104,8 +104,8 @@ const x: string = foo[_private]; const y: string = foo[strMem]; >y : string > : ^^^^^^ ->foo[strMem] : string -> : ^^^^^^ +>foo[strMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >strMem : "strMemName" @@ -114,8 +114,8 @@ const y: string = foo[strMem]; const z: string = foo[numMem]; >z : string > : ^^^^^^ ->foo[numMem] : string -> : ^^^^^^ +>foo[numMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >numMem : 42 @@ -124,8 +124,8 @@ const z: string = foo[numMem]; const a: string = foo[dashStrMem]; >a : string > : ^^^^^^ ->foo[dashStrMem] : string -> : ^^^^^^ +>foo[dashStrMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >dashStrMem : "dashed-str-mem" diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments2.errors.txt b/tests/baselines/reference/declarationEmitLateBoundAssignments2.errors.txt new file mode 100644 index 0000000000000..dcd286b4c4b03 --- /dev/null +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments2.errors.txt @@ -0,0 +1,121 @@ +declarationEmitLateBoundAssignments2.ts(13,1): error TS7053: Element implicitly has an 'any' type because expression of type '"C"' can't be used to index type 'typeof decl2'. + Property 'C' does not exist on type 'typeof decl2'. +declarationEmitLateBoundAssignments2.ts(19,1): error TS7053: Element implicitly has an 'any' type because expression of type '1' can't be used to index type 'typeof decl4'. + Property '1' does not exist on type 'typeof decl4'. +declarationEmitLateBoundAssignments2.ts(25,1): error TS7053: Element implicitly has an 'any' type because expression of type '"10"' can't be used to index type 'typeof decl6'. + Property '10' does not exist on type 'typeof decl6'. +declarationEmitLateBoundAssignments2.ts(31,1): error TS7053: Element implicitly has an 'any' type because expression of type '"foo bar"' can't be used to index type 'typeof decl8'. + Property 'foo bar' does not exist on type 'typeof decl8'. +declarationEmitLateBoundAssignments2.ts(37,1): error TS7053: Element implicitly has an 'any' type because expression of type '"🤷‍♂️"' can't be used to index type 'typeof decl10'. + Property '🤷‍♂️' does not exist on type 'typeof decl10'. +declarationEmitLateBoundAssignments2.ts(43,1): error TS7053: Element implicitly has an 'any' type because expression of type '"C"' can't be used to index type '() => void'. + Property 'C' does not exist on type '() => void'. +declarationEmitLateBoundAssignments2.ts(49,1): error TS7053: Element implicitly has an 'any' type because expression of type '1' can't be used to index type '() => void'. + Property '1' does not exist on type '() => void'. +declarationEmitLateBoundAssignments2.ts(55,1): error TS7053: Element implicitly has an 'any' type because expression of type '"10"' can't be used to index type '() => void'. + Property '10' does not exist on type '() => void'. +declarationEmitLateBoundAssignments2.ts(61,1): error TS7053: Element implicitly has an 'any' type because expression of type '"foo bar"' can't be used to index type '() => void'. + Property 'foo bar' does not exist on type '() => void'. +declarationEmitLateBoundAssignments2.ts(67,1): error TS7053: Element implicitly has an 'any' type because expression of type '"🤷‍♂️"' can't be used to index type '() => void'. + Property '🤷‍♂️' does not exist on type '() => void'. + + +==== declarationEmitLateBoundAssignments2.ts (10 errors) ==== + // https://github.com/microsoft/TypeScript/issues/54811 + + const c = "C" + const num = 1 + const numStr = "10" + const withWhitespace = "foo bar" + const emoji = "🤷‍♂️" + + export function decl() {} + decl["B"] = 'foo' + + export function decl2() {} + decl2[c] = 0 + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"C"' can't be used to index type 'typeof decl2'. +!!! error TS7053: Property 'C' does not exist on type 'typeof decl2'. + + export function decl3() {} + decl3[77] = 0 + + export function decl4() {} + decl4[num] = 0 + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '1' can't be used to index type 'typeof decl4'. +!!! error TS7053: Property '1' does not exist on type 'typeof decl4'. + + export function decl5() {} + decl5["101"] = 0 + + export function decl6() {} + decl6[numStr] = 0 + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"10"' can't be used to index type 'typeof decl6'. +!!! error TS7053: Property '10' does not exist on type 'typeof decl6'. + + export function decl7() {} + decl7["qwe rty"] = 0 + + export function decl8() {} + decl8[withWhitespace] = 0 + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"foo bar"' can't be used to index type 'typeof decl8'. +!!! error TS7053: Property 'foo bar' does not exist on type 'typeof decl8'. + + export function decl9() {} + decl9["🤪"] = 0 + + export function decl10() {} + decl10[emoji] = 0 + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"🤷‍♂️"' can't be used to index type 'typeof decl10'. +!!! error TS7053: Property '🤷‍♂️' does not exist on type 'typeof decl10'. + + export const arrow = () => {} + arrow["B"] = 'bar' + + export const arrow2 = () => {} + arrow2[c] = 100 + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"C"' can't be used to index type '() => void'. +!!! error TS7053: Property 'C' does not exist on type '() => void'. + + export const arrow3 = () => {} + arrow3[77] = 0 + + export const arrow4 = () => {} + arrow4[num] = 0 + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '1' can't be used to index type '() => void'. +!!! error TS7053: Property '1' does not exist on type '() => void'. + + export const arrow5 = () => {} + arrow5["101"] = 0 + + export const arrow6 = () => {} + arrow6[numStr] = 0 + ~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"10"' can't be used to index type '() => void'. +!!! error TS7053: Property '10' does not exist on type '() => void'. + + export const arrow7 = () => {} + arrow7["qwe rty"] = 0 + + export const arrow8 = () => {} + arrow8[withWhitespace] = 0 + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"foo bar"' can't be used to index type '() => void'. +!!! error TS7053: Property 'foo bar' does not exist on type '() => void'. + + export const arrow9 = () => {} + arrow9["🤪"] = 0 + + export const arrow10 = () => {} + arrow10[emoji] = 0 + ~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"🤷‍♂️"' can't be used to index type '() => void'. +!!! error TS7053: Property '🤷‍♂️' does not exist on type '() => void'. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments2.js b/tests/baselines/reference/declarationEmitLateBoundAssignments2.js index 1b150435028d8..1fb936f7b8fbb 100644 --- a/tests/baselines/reference/declarationEmitLateBoundAssignments2.js +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments2.js @@ -125,62 +125,40 @@ export declare namespace decl { var B: string; } export declare function decl2(): void; -export declare namespace decl2 { - var C: number; -} export declare function decl3(): void; export declare namespace decl3 { } export declare function decl4(): void; -export declare namespace decl4 { } export declare function decl5(): void; export declare namespace decl5 { } export declare function decl6(): void; -export declare namespace decl6 { } export declare function decl7(): void; export declare namespace decl7 { } export declare function decl8(): void; -export declare namespace decl8 { } export declare function decl9(): void; export declare namespace decl9 { } export declare function decl10(): void; -export declare namespace decl10 { } export declare const arrow: { (): void; B: string; }; -export declare const arrow2: { - (): void; - C: number; -}; +export declare const arrow2: () => void; export declare const arrow3: { (): void; 77: number; }; -export declare const arrow4: { - (): void; - 1: number; -}; +export declare const arrow4: () => void; export declare const arrow5: { (): void; "101": number; }; -export declare const arrow6: { - (): void; - "10": number; -}; +export declare const arrow6: () => void; export declare const arrow7: { (): void; "qwe rty": number; }; -export declare const arrow8: { - (): void; - "foo bar": number; -}; +export declare const arrow8: () => void; export declare const arrow9: { (): void; "\uD83E\uDD2A": number; }; -export declare const arrow10: { - (): void; - "\uD83E\uDD37\u200D\u2642\uFE0F": number; -}; +export declare const arrow10: () => void; diff --git a/tests/baselines/reference/declarationEmitLateBoundAssignments2.types b/tests/baselines/reference/declarationEmitLateBoundAssignments2.types index 72e3e7bd20533..26c388fd50519 100644 --- a/tests/baselines/reference/declarationEmitLateBoundAssignments2.types +++ b/tests/baselines/reference/declarationEmitLateBoundAssignments2.types @@ -56,8 +56,8 @@ export function decl2() {} decl2[c] = 0 >decl2[c] = 0 : 0 > : ^ ->decl2[c] : number -> : ^^^^^^ +>decl2[c] : any +> : ^^^ >decl2 : typeof decl2 > : ^^^^^^^^^^^^ >c : "C" @@ -88,8 +88,8 @@ export function decl4() {} decl4[num] = 0 >decl4[num] = 0 : 0 > : ^ ->decl4[num] : number -> : ^^^^^^ +>decl4[num] : any +> : ^^^ >decl4 : typeof decl4 > : ^^^^^^^^^^^^ >num : 1 @@ -120,8 +120,8 @@ export function decl6() {} decl6[numStr] = 0 >decl6[numStr] = 0 : 0 > : ^ ->decl6[numStr] : number -> : ^^^^^^ +>decl6[numStr] : any +> : ^^^ >decl6 : typeof decl6 > : ^^^^^^^^^^^^ >numStr : "10" @@ -152,8 +152,8 @@ export function decl8() {} decl8[withWhitespace] = 0 >decl8[withWhitespace] = 0 : 0 > : ^ ->decl8[withWhitespace] : number -> : ^^^^^^ +>decl8[withWhitespace] : any +> : ^^^ >decl8 : typeof decl8 > : ^^^^^^^^^^^^ >withWhitespace : "foo bar" @@ -184,8 +184,8 @@ export function decl10() {} decl10[emoji] = 0 >decl10[emoji] = 0 : 0 > : ^ ->decl10[emoji] : number -> : ^^^^^^ +>decl10[emoji] : any +> : ^^^ >decl10 : typeof decl10 > : ^^^^^^^^^^^^^ >emoji : "🤷‍♂️" @@ -212,18 +212,18 @@ arrow["B"] = 'bar' > : ^^^^^ export const arrow2 = () => {} ->arrow2 : { (): void; C: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ ->() => {} : { (): void; C: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow2 : () => void +> : ^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ arrow2[c] = 100 >arrow2[c] = 100 : 100 > : ^^^ ->arrow2[c] : number -> : ^^^^^^ ->arrow2 : { (): void; C: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow2[c] : any +> : ^^^ +>arrow2 : () => void +> : ^^^^^^^^^^ >c : "C" > : ^^^ >100 : 100 @@ -248,18 +248,18 @@ arrow3[77] = 0 > : ^ export const arrow4 = () => {} ->arrow4 : { (): void; 1: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ ->() => {} : { (): void; 1: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow4 : () => void +> : ^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ arrow4[num] = 0 >arrow4[num] = 0 : 0 > : ^ ->arrow4[num] : number -> : ^^^^^^ ->arrow4 : { (): void; 1: number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow4[num] : any +> : ^^^ +>arrow4 : () => void +> : ^^^^^^^^^^ >num : 1 > : ^ >0 : 0 @@ -284,18 +284,18 @@ arrow5["101"] = 0 > : ^ export const arrow6 = () => {} ->arrow6 : { (): void; "10": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->() => {} : { (): void; "10": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow6 : () => void +> : ^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ arrow6[numStr] = 0 >arrow6[numStr] = 0 : 0 > : ^ ->arrow6[numStr] : number -> : ^^^^^^ ->arrow6 : { (): void; "10": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow6[numStr] : any +> : ^^^ +>arrow6 : () => void +> : ^^^^^^^^^^ >numStr : "10" > : ^^^^ >0 : 0 @@ -320,18 +320,18 @@ arrow7["qwe rty"] = 0 > : ^ export const arrow8 = () => {} ->arrow8 : { (): void; "foo bar": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->() => {} : { (): void; "foo bar": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow8 : () => void +> : ^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ arrow8[withWhitespace] = 0 >arrow8[withWhitespace] = 0 : 0 > : ^ ->arrow8[withWhitespace] : number -> : ^^^^^^ ->arrow8 : { (): void; "foo bar": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow8[withWhitespace] : any +> : ^^^ +>arrow8 : () => void +> : ^^^^^^^^^^ >withWhitespace : "foo bar" > : ^^^^^^^^^ >0 : 0 @@ -356,18 +356,18 @@ arrow9["🤪"] = 0 > : ^ export const arrow10 = () => {} ->arrow10 : { (): void; "\uD83E\uDD37\u200D\u2642\uFE0F": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->() => {} : { (): void; "\uD83E\uDD37\u200D\u2642\uFE0F": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow10 : () => void +> : ^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ arrow10[emoji] = 0 >arrow10[emoji] = 0 : 0 > : ^ ->arrow10[emoji] : number -> : ^^^^^^ ->arrow10 : { (): void; "\uD83E\uDD37\u200D\u2642\uFE0F": number; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arrow10[emoji] : any +> : ^^^ +>arrow10 : () => void +> : ^^^^^^^^^^ >emoji : "🤷‍♂️" > : ^^^^^^^ >0 : 0 diff --git a/tests/baselines/reference/declarationEmitLateBoundJSAssignments.errors.txt b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.errors.txt new file mode 100644 index 0000000000000..33c16f5661b35 --- /dev/null +++ b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.errors.txt @@ -0,0 +1,63 @@ +file.js(4,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. +file.js(6,1): error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. + Property 'strMemName' does not exist on type 'typeof foo'. +file.js(8,1): error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. + Property 'dashed-str-mem' does not exist on type 'typeof foo'. +file.js(10,1): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. + Property '42' does not exist on type 'typeof foo'. +file.js(13,11): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. +file.js(15,11): error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. + Property 'strMemName' does not exist on type 'typeof foo'. +file.js(17,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. + Property '42' does not exist on type 'typeof foo'. +file.js(19,11): error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. + Property 'dashed-str-mem' does not exist on type 'typeof foo'. + + +==== file.js (8 errors) ==== + export function foo() {} + foo.bar = 12; + const _private = Symbol(); + foo[_private] = "ok"; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + const strMem = "strMemName"; + foo[strMem] = "ok"; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'strMemName' does not exist on type 'typeof foo'. + const dashStrMem = "dashed-str-mem"; + foo[dashStrMem] = "ok"; + ~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'dashed-str-mem' does not exist on type 'typeof foo'. + const numMem = 42; + foo[numMem] = "ok"; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '42' does not exist on type 'typeof foo'. + + /** @type {string} */ + const x = foo[_private]; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + /** @type {string} */ + const y = foo[strMem]; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"strMemName"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'strMemName' does not exist on type 'typeof foo'. + /** @type {string} */ + const z = foo[numMem]; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '42' does not exist on type 'typeof foo'. + /** @type {string} */ + const a = foo[dashStrMem]; + ~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"dashed-str-mem"' can't be used to index type 'typeof foo'. +!!! error TS7053: Property 'dashed-str-mem' does not exist on type 'typeof foo'. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitLateBoundJSAssignments.js b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.js index 56d1f7860c715..09ce30e05fd35 100644 --- a/tests/baselines/reference/declarationEmitLateBoundJSAssignments.js +++ b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.js @@ -28,5 +28,4 @@ const a = foo[dashStrMem]; export function foo(): void; export namespace foo { let bar: number; - let strMemName: string; } diff --git a/tests/baselines/reference/declarationEmitLateBoundJSAssignments.types b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.types index 91cd4d75e4607..845e1b71ba4a7 100644 --- a/tests/baselines/reference/declarationEmitLateBoundJSAssignments.types +++ b/tests/baselines/reference/declarationEmitLateBoundJSAssignments.types @@ -28,8 +28,8 @@ const _private = Symbol(); foo[_private] = "ok"; >foo[_private] = "ok" : "ok" > : ^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol @@ -46,8 +46,8 @@ const strMem = "strMemName"; foo[strMem] = "ok"; >foo[strMem] = "ok" : "ok" > : ^^^^ ->foo[strMem] : string -> : ^^^^^^ +>foo[strMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >strMem : "strMemName" @@ -64,8 +64,8 @@ const dashStrMem = "dashed-str-mem"; foo[dashStrMem] = "ok"; >foo[dashStrMem] = "ok" : "ok" > : ^^^^ ->foo[dashStrMem] : string -> : ^^^^^^ +>foo[dashStrMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >dashStrMem : "dashed-str-mem" @@ -82,8 +82,8 @@ const numMem = 42; foo[numMem] = "ok"; >foo[numMem] = "ok" : "ok" > : ^^^^ ->foo[numMem] : string -> : ^^^^^^ +>foo[numMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >numMem : 42 @@ -95,8 +95,8 @@ foo[numMem] = "ok"; const x = foo[_private]; >x : string > : ^^^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol @@ -106,8 +106,8 @@ const x = foo[_private]; const y = foo[strMem]; >y : string > : ^^^^^^ ->foo[strMem] : string -> : ^^^^^^ +>foo[strMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >strMem : "strMemName" @@ -117,8 +117,8 @@ const y = foo[strMem]; const z = foo[numMem]; >z : string > : ^^^^^^ ->foo[numMem] : string -> : ^^^^^^ +>foo[numMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >numMem : 42 @@ -128,8 +128,8 @@ const z = foo[numMem]; const a = foo[dashStrMem]; >a : string > : ^^^^^^ ->foo[dashStrMem] : string -> : ^^^^^^ +>foo[dashStrMem] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >dashStrMem : "dashed-str-mem" diff --git a/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.errors.txt b/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.errors.txt new file mode 100644 index 0000000000000..6f6de7d73a020 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.errors.txt @@ -0,0 +1,26 @@ +expandoFunctionExpressionsWithDynamicNames2.ts(6,7): error TS2741: Property '[mySymbol]' is missing in type '() => void' but required in type 'Foo'. +expandoFunctionExpressionsWithDynamicNames2.ts(14,7): error TS2741: Property 'test' is missing in type '() => void' but required in type 'Bar'. + + +==== expandoFunctionExpressionsWithDynamicNames2.ts (2 errors) ==== + const mySymbol = Symbol(); + interface Foo { + (): void; + [mySymbol]: true; + } + const foo: Foo = () => {}; + ~~~ +!!! error TS2741: Property '[mySymbol]' is missing in type '() => void' but required in type 'Foo'. +!!! related TS2728 expandoFunctionExpressionsWithDynamicNames2.ts:4:3: '[mySymbol]' is declared here. + foo[mySymbol] = true; + + interface Bar { + (): void; + test: true; + } + const t = "test" as const; + const bar: Bar = () => {}; + ~~~ +!!! error TS2741: Property 'test' is missing in type '() => void' but required in type 'Bar'. +!!! related TS2728 expandoFunctionExpressionsWithDynamicNames2.ts:11:3: 'test' is declared here. + bar[t] = true; \ No newline at end of file diff --git a/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.types b/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.types index 0c16ddfe254ec..657e2028f28a5 100644 --- a/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.types +++ b/tests/baselines/reference/expandoFunctionExpressionsWithDynamicNames2.types @@ -22,8 +22,8 @@ interface Foo { const foo: Foo = () => {}; >foo : Foo > : ^^^ ->() => {} : { (): void; [mySymbol]: true; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ foo[mySymbol] = true; >foo[mySymbol] = true : true @@ -56,8 +56,8 @@ const t = "test" as const; const bar: Bar = () => {}; >bar : Bar > : ^^^ ->() => {} : { (): void; test: true; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>() => {} : () => void +> : ^^^^^^^^^^ bar[t] = true; >bar[t] = true : true diff --git a/tests/baselines/reference/expandoFunctionSymbolProperty.errors.txt b/tests/baselines/reference/expandoFunctionSymbolProperty.errors.txt new file mode 100644 index 0000000000000..a65b78577de31 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolProperty.errors.txt @@ -0,0 +1,27 @@ +expandoFunctionSymbolProperty.ts(12,3): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '() => void'. + Property '[symb]' does not exist on type '() => void'. +expandoFunctionSymbolProperty.ts(13,3): error TS2741: Property '[symb]' is missing in type '() => void' but required in type 'TestSymb'. + + +==== expandoFunctionSymbolProperty.ts (2 errors) ==== + // repro from https://github.com/microsoft/TypeScript/issues/54220 + + const symb = Symbol(); + + interface TestSymb { + (): void; + readonly [symb]: boolean; + } + + export function test(): TestSymb { + function inner() {} + inner[symb] = true; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '() => void'. +!!! error TS7053: Property '[symb]' does not exist on type '() => void'. + return inner; + ~~~~~~ +!!! error TS2741: Property '[symb]' is missing in type '() => void' but required in type 'TestSymb'. +!!! related TS2728 expandoFunctionSymbolProperty.ts:7:12: '[symb]' is declared here. + } + \ No newline at end of file diff --git a/tests/baselines/reference/expandoFunctionSymbolProperty.types b/tests/baselines/reference/expandoFunctionSymbolProperty.types index d119b79c0e79e..4335d8ad19238 100644 --- a/tests/baselines/reference/expandoFunctionSymbolProperty.types +++ b/tests/baselines/reference/expandoFunctionSymbolProperty.types @@ -25,23 +25,23 @@ export function test(): TestSymb { > : ^^^^^^ function inner() {} ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : () => void +> : ^^^^^^^^^^ inner[symb] = true; >inner[symb] = true : true > : ^^^^ ->inner[symb] : boolean -> : ^^^^^^^ ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner[symb] : any +> : ^^^ +>inner : () => void +> : ^^^^^^^^^^ >symb : unique symbol > : ^^^^^^^^^^^^^ >true : true > : ^^^^ return inner; ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : () => void +> : ^^^^^^^^^^ } diff --git a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.errors.txt b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.errors.txt new file mode 100644 index 0000000000000..eed6de7a404b7 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.errors.txt @@ -0,0 +1,30 @@ +/a.js(8,3): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '() => void'. + Property '["./types".symb]' does not exist on type '() => void'. +/a.js(9,3): error TS2741: Property '[symb]' is missing in type '() => void' but required in type 'TestSymb'. + + +==== /types.ts (0 errors) ==== + export const symb = Symbol(); + + export interface TestSymb { + (): void; + readonly [symb]: boolean; + } + +==== /a.js (2 errors) ==== + import { symb } from "./types"; + + /** + * @returns {import("./types").TestSymb} + */ + export function test() { + function inner() {} + inner[symb] = true; + ~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '() => void'. +!!! error TS7053: Property '["./types".symb]' does not exist on type '() => void'. + return inner; + ~~~~~~ +!!! error TS2741: Property '[symb]' is missing in type '() => void' but required in type 'TestSymb'. +!!! related TS2728 /types.ts:5:12: '[symb]' is declared here. + } \ No newline at end of file diff --git a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types index d3f70eb1a1fc3..bddcb19f25a61 100644 --- a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types +++ b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types @@ -31,22 +31,22 @@ export function test() { > : ^^^^^^ function inner() {} ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : () => void +> : ^^^^^^^^^^ inner[symb] = true; >inner[symb] = true : true > : ^^^^ ->inner[symb] : boolean -> : ^^^^^^^ ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner[symb] : any +> : ^^^ +>inner : () => void +> : ^^^^^^^^^^ >symb : unique symbol > : ^^^^^^^^^^^^^ >true : true > : ^^^^ return inner; ->inner : { (): void; [symb]: boolean; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : () => void +> : ^^^^^^^^^^ } diff --git a/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt b/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt index 6931ab5f5df2b..9a3cc0bbeb433 100644 --- a/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt +++ b/tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt @@ -1,12 +1,10 @@ isolatedDeclarationLazySymbols.ts(1,17): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations. -isolatedDeclarationLazySymbols.ts(12,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. -isolatedDeclarationLazySymbols.ts(13,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. isolatedDeclarationLazySymbols.ts(16,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. isolatedDeclarationLazySymbols.ts(21,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations. -==== isolatedDeclarationLazySymbols.ts (6 errors) ==== +==== isolatedDeclarationLazySymbols.ts (4 errors) ==== export function foo() { ~~~ !!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations. @@ -22,11 +20,7 @@ isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names o } as const foo[o["prop.inner"]] ="A"; - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. foo[o.prop.inner] = "B"; - ~~~~~~~~~~~~~~~~~ -!!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function. export class Foo { [o["prop.inner"]] ="A" diff --git a/tests/baselines/reference/isolatedDeclarationLazySymbols.types b/tests/baselines/reference/isolatedDeclarationLazySymbols.types index 5a1bfe22638bd..cf461fa0b3be9 100644 --- a/tests/baselines/reference/isolatedDeclarationLazySymbols.types +++ b/tests/baselines/reference/isolatedDeclarationLazySymbols.types @@ -40,8 +40,8 @@ const o = { foo[o["prop.inner"]] ="A"; >foo[o["prop.inner"]] ="A" : "A" > : ^^^ ->foo[o["prop.inner"]] : string -> : ^^^^^^ +>foo[o["prop.inner"]] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >o["prop.inner"] : "a" @@ -56,8 +56,8 @@ foo[o["prop.inner"]] ="A"; foo[o.prop.inner] = "B"; >foo[o.prop.inner] = "B" : "B" > : ^^^ ->foo[o.prop.inner] : string -> : ^^^^^^ +>foo[o.prop.inner] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >o.prop.inner : "b" diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols index 90d7466bdb7bd..a0795d5438725 100644 --- a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols @@ -18,6 +18,6 @@ export class foo2 { * @type {string} */ prop = 'baz'; ->prop : Symbol(foo2.prop, Decl(index.js, 5, 5), Decl(index.js, 3, 19)) +>prop : Symbol(foo2.prop, Decl(index.js, 5, 5)) } diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.errors.txt b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.errors.txt new file mode 100644 index 0000000000000..a936cb7b77f88 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.errors.txt @@ -0,0 +1,37 @@ +lateBoundAssignmentDeclarationSupport7.js(6,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof F'. + Property '[_sym]' does not exist on type 'typeof F'. +lateBoundAssignmentDeclarationSupport7.js(7,1): error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'typeof F'. + Property 'my-fake-sym' does not exist on type 'typeof F'. +usage.js(2,11): error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'typeof F'. + Property 'my-fake-sym' does not exist on type 'typeof F'. +usage.js(3,11): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof F'. + Property '[_sym]' does not exist on type 'typeof F'. + + +==== usage.js (2 errors) ==== + const x = require("./lateBoundAssignmentDeclarationSupport7.js"); + const y = x.F["my-fake-sym"]; + ~~~~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'typeof F'. +!!! error TS7053: Property 'my-fake-sym' does not exist on type 'typeof F'. + const z = x.F[x.S]; + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof F'. +!!! error TS7053: Property '[_sym]' does not exist on type 'typeof F'. + +==== lateBoundAssignmentDeclarationSupport7.js (2 errors) ==== + const _sym = Symbol(); + const _str = "my-fake-sym"; + + function F() { + } + F[_sym] = "ok"; + ~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof F'. +!!! error TS7053: Property '[_sym]' does not exist on type 'typeof F'. + F[_str] = "ok"; + ~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'typeof F'. +!!! error TS7053: Property 'my-fake-sym' does not exist on type 'typeof F'. + module.exports.F = F; + module.exports.S = _sym; \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols index 374e7ac0c4081..029a3f5aef82d 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.symbols @@ -11,7 +11,6 @@ const y = x.F["my-fake-sym"]; >x.F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) >x : Symbol(x, Decl(usage.js, 0, 5)) >F : Symbol(x.F, Decl(lateBoundAssignmentDeclarationSupport7.js, 6, 15)) ->"my-fake-sym" : Symbol(x.F.F[_str], Decl(lateBoundAssignmentDeclarationSupport7.js, 5, 15)) const z = x.F[x.S]; >z : Symbol(z, Decl(usage.js, 2, 5)) diff --git a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types index aa14b43f44c10..7962daa4507f7 100644 --- a/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types +++ b/tests/baselines/reference/lateBoundAssignmentDeclarationSupport7.types @@ -7,14 +7,15 @@ const x = require("./lateBoundAssignmentDeclarationSupport7.js"); >require("./lateBoundAssignmentDeclarationSupport7.js") : typeof x > : ^^^^^^^^ >require : any +> : ^^^ >"./lateBoundAssignmentDeclarationSupport7.js" : "./lateBoundAssignmentDeclarationSupport7.js" > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ const y = x.F["my-fake-sym"]; ->y : string -> : ^^^^^^ ->x.F["my-fake-sym"] : string -> : ^^^^^^ +>y : any +> : ^^^ +>x.F["my-fake-sym"] : any +> : ^^^ >x.F : typeof x.F > : ^^^^^^^^^^ >x : typeof x @@ -25,10 +26,10 @@ const y = x.F["my-fake-sym"]; > : ^^^^^^^^^^^^^ const z = x.F[x.S]; ->z : string -> : ^^^^^^ ->x.F[x.S] : string -> : ^^^^^^ +>z : any +> : ^^^ +>x.F[x.S] : any +> : ^^^ >x.F : typeof x.F > : ^^^^^^^^^^ >x : typeof x @@ -64,8 +65,8 @@ function F() { F[_sym] = "ok"; >F[_sym] = "ok" : "ok" > : ^^^^ ->F[_sym] : string -> : ^^^^^^ +>F[_sym] : any +> : ^^^ >F : typeof F > : ^^^^^^^^ >_sym : unique symbol @@ -76,8 +77,8 @@ F[_sym] = "ok"; F[_str] = "ok"; >F[_str] = "ok" : "ok" > : ^^^^ ->F[_str] : string -> : ^^^^^^ +>F[_str] : any +> : ^^^ >F : typeof F > : ^^^^^^^^ >_str : "my-fake-sym" diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS.errors.txt b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.errors.txt new file mode 100644 index 0000000000000..c23415b953d85 --- /dev/null +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.errors.txt @@ -0,0 +1,29 @@ +lateBoundClassMemberAssignmentJS.js(4,9): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS.js(8,9): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS.js(9,19): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. + + +==== lateBoundClassMemberAssignmentJS.js (3 errors) ==== + const _sym = Symbol("_sym"); + export class MyClass { + constructor() { + this[_sym] = "ok"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + } + + method() { + this[_sym] = "yep"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + const x = this[_sym]; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS.js b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.js index 89bad95c9e221..e5bf031df098f 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS.js +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.js @@ -18,7 +18,4 @@ export class MyClass { //// [lateBoundClassMemberAssignmentJS.d.ts] export class MyClass { method(): void; - [_sym]: string; } -declare const _sym: unique symbol; -export {}; diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS.types b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.types index 7bc923eebf8fd..872c381306522 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS.types +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS.types @@ -19,8 +19,8 @@ export class MyClass { this[_sym] = "ok"; >this[_sym] = "ok" : "ok" > : ^^^^ ->this[_sym] : string -> : ^^^^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : unique symbol @@ -36,8 +36,8 @@ export class MyClass { this[_sym] = "yep"; >this[_sym] = "yep" : "yep" > : ^^^^^ ->this[_sym] : string -> : ^^^^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : unique symbol @@ -46,10 +46,10 @@ export class MyClass { > : ^^^^^ const x = this[_sym]; ->x : string -> : ^^^^^^ ->this[_sym] : string -> : ^^^^^^ +>x : any +> : ^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : unique symbol diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.errors.txt b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.errors.txt new file mode 100644 index 0000000000000..07fd66af4dcf6 --- /dev/null +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.errors.txt @@ -0,0 +1,29 @@ +lateBoundClassMemberAssignmentJS2.js(4,9): error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. + Property 'my-fake-sym' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS2.js(8,9): error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. + Property 'my-fake-sym' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS2.js(9,19): error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. + Property 'my-fake-sym' does not exist on type 'MyClass'. + + +==== lateBoundClassMemberAssignmentJS2.js (3 errors) ==== + const _sym = "my-fake-sym"; + export class MyClass { + constructor() { + this[_sym] = "ok"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. +!!! error TS7053: Property 'my-fake-sym' does not exist on type 'MyClass'. + } + + method() { + this[_sym] = "yep"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. +!!! error TS7053: Property 'my-fake-sym' does not exist on type 'MyClass'. + const x = this[_sym]; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"my-fake-sym"' can't be used to index type 'MyClass'. +!!! error TS7053: Property 'my-fake-sym' does not exist on type 'MyClass'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.js b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.js index d262ba83a743d..1d7a15a12bb33 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.js +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.js @@ -18,5 +18,4 @@ export class MyClass { //// [lateBoundClassMemberAssignmentJS2.d.ts] export class MyClass { method(): void; - "my-fake-sym": string; } diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.types b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.types index e109356d8059d..b4985f5c29d38 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.types +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS2.types @@ -15,8 +15,8 @@ export class MyClass { this[_sym] = "ok"; >this[_sym] = "ok" : "ok" > : ^^^^ ->this[_sym] : string -> : ^^^^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : "my-fake-sym" @@ -32,8 +32,8 @@ export class MyClass { this[_sym] = "yep"; >this[_sym] = "yep" : "yep" > : ^^^^^ ->this[_sym] : string -> : ^^^^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : "my-fake-sym" @@ -42,10 +42,10 @@ export class MyClass { > : ^^^^^ const x = this[_sym]; ->x : string -> : ^^^^^^ ->this[_sym] : string -> : ^^^^^^ +>x : any +> : ^^^ +>this[_sym] : any +> : ^^^ >this : this > : ^^^^ >_sym : "my-fake-sym" diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.errors.txt b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.errors.txt new file mode 100644 index 0000000000000..19591109448d6 --- /dev/null +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.errors.txt @@ -0,0 +1,32 @@ +lateBoundClassMemberAssignmentJS.js(5,9): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS.js(10,9): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. +lateBoundClassMemberAssignmentJS.js(11,19): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. + Property '[_sym]' does not exist on type 'MyClass'. + + +==== lateBoundClassMemberAssignmentJS.js (3 errors) ==== + const _sym = Symbol("_sym"); + export class MyClass { + constructor() { + var self = this + self[_sym] = "ok"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + } + + method() { + var self = this + self[_sym] = "yep"; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + const x = self[_sym]; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'MyClass'. +!!! error TS7053: Property '[_sym]' does not exist on type 'MyClass'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.js b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.js index 848f904b3f77f..1cd9be0b84b50 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.js +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.js @@ -21,7 +21,4 @@ export class MyClass { //// [lateBoundClassMemberAssignmentJS.d.ts] export class MyClass { method(): void; - [_sym]: string; } -declare const _sym: unique symbol; -export {}; diff --git a/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.types b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.types index d5f23f26935f3..bacbcbc4f3123 100644 --- a/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.types +++ b/tests/baselines/reference/lateBoundClassMemberAssignmentJS3.types @@ -25,8 +25,8 @@ export class MyClass { self[_sym] = "ok"; >self[_sym] = "ok" : "ok" > : ^^^^ ->self[_sym] : string -> : ^^^^^^ +>self[_sym] : any +> : ^^^ >self : this > : ^^^^ >_sym : unique symbol @@ -48,8 +48,8 @@ export class MyClass { self[_sym] = "yep"; >self[_sym] = "yep" : "yep" > : ^^^^^ ->self[_sym] : string -> : ^^^^^^ +>self[_sym] : any +> : ^^^ >self : this > : ^^^^ >_sym : unique symbol @@ -58,10 +58,10 @@ export class MyClass { > : ^^^^^ const x = self[_sym]; ->x : string -> : ^^^^^^ ->self[_sym] : string -> : ^^^^^^ +>x : any +> : ^^^ +>self[_sym] : any +> : ^^^ >self : this > : ^^^^ >_sym : unique symbol diff --git a/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.errors.txt b/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.errors.txt new file mode 100644 index 0000000000000..fb0ea1e5a1077 --- /dev/null +++ b/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.errors.txt @@ -0,0 +1,20 @@ +index.ts(4,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. +index.ts(6,19): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. + Property '[_private]' does not exist on type 'typeof foo'. + + +==== index.ts (2 errors) ==== + export function foo() {} + foo.bar = 12; + const _private = Symbol(); + foo[_private] = "ok"; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + + const x: string = foo[_private]; + ~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'typeof foo'. +!!! error TS7053: Property '[_private]' does not exist on type 'typeof foo'. + \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.types b/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.types index bdfd18445c714..3b7e6cb6bf1fc 100644 --- a/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.types +++ b/tests/baselines/reference/lateBoundFunctionMemberAssignmentDeclarations.types @@ -28,8 +28,8 @@ const _private = Symbol(); foo[_private] = "ok"; >foo[_private] = "ok" : "ok" > : ^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol @@ -40,8 +40,8 @@ foo[_private] = "ok"; const x: string = foo[_private]; >x : string > : ^^^^^^ ->foo[_private] : string -> : ^^^^^^ +>foo[_private] : any +> : ^^^ >foo : typeof foo > : ^^^^^^^^^^ >_private : unique symbol diff --git a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js index fa537a6cb9b75..8124f724c81ee 100644 --- a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js +++ b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js @@ -14,7 +14,7 @@ export class MyClass { //// [lateBoundMethodNameAssigmentJS.d.ts] export class MyClass { - [_symbol]: () => Promise; + [_symbol](): Promise; } declare const _symbol: unique symbol; export {}; diff --git a/tests/baselines/reference/wellKnownSymbolExpando.types b/tests/baselines/reference/wellKnownSymbolExpando.types index d8015edeebaf6..3091e1e1d2763 100644 --- a/tests/baselines/reference/wellKnownSymbolExpando.types +++ b/tests/baselines/reference/wellKnownSymbolExpando.types @@ -8,7 +8,7 @@ function f() {} f[Symbol.iterator] = function() {} >f[Symbol.iterator] = function() {} : () => void > : ^^^^^^^^^^ ->f[Symbol.iterator] : any +>f[Symbol.iterator] : error >f : typeof f > : ^^^^^^^^ >Symbol.iterator : unique symbol