diff --git a/src/compat/deprecations.ts b/src/compat/deprecations.ts index ed1034b7e6a1b..2ea2c7ac5a769 100644 --- a/src/compat/deprecations.ts +++ b/src/compat/deprecations.ts @@ -1215,7 +1215,7 @@ namespace ts { }, factoryDeprecation); /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ - export const createJSDocParamTag = Debug.deprecate(function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag { + export const createJSDocParamTag = Debug.deprecate(function createJSDocParamTag(name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag { return factory.createJSDocParameterTag(/*tagName*/ undefined, name, isBracketed, typeExpression, /*isNameFirst*/ false, comment); }, factoryDeprecation); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a9d11787a14a3..b9dd040f5c396 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1658,7 +1658,7 @@ namespace ts { name: __String, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage | undefined, - nameArg: __String | Identifier | undefined, + nameArg: __String | Identifier | StringLiteralLike | undefined, isUse: boolean, excludeGlobals = false, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol | undefined { @@ -1670,7 +1670,7 @@ namespace ts { name: __String, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage | undefined, - nameArg: __String | Identifier | undefined, + nameArg: __String | Identifier | StringLiteralLike | undefined, isUse: boolean, excludeGlobals: boolean, lookup: typeof getSymbol, @@ -2132,7 +2132,7 @@ namespace ts { } } - function diagnosticName(nameArg: __String | Identifier | PrivateIdentifier) { + function diagnosticName(nameArg: __String | Identifier | StringLiteralLike | PrivateIdentifier) { return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); } @@ -2149,7 +2149,7 @@ namespace ts { return false; } - function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: __String, nameArg: __String | Identifier): boolean { + function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: __String, nameArg: __String | StringLiteralLike | Identifier): boolean { if (!isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) { return false; } @@ -2222,7 +2222,7 @@ namespace ts { if (symbol) { if (isQualifiedName(parent)) { Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace"); - const propName = parent.right.escapedText; + const propName = qualifiedNameTextRaw(parent.right); const propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName); if (propType) { error( @@ -3046,10 +3046,10 @@ namespace ts { const namespaceMeaning = SymbolFlags.Namespace | (isInJSFile(name) ? meaning & SymbolFlags.Value : 0); let symbol: Symbol | undefined; - if (name.kind === SyntaxKind.Identifier) { + if (name.kind === SyntaxKind.Identifier || isStringLiteralLike(name)) { const message = meaning === namespaceMeaning || nodeIsSynthesized(name) ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name)); const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined; - symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true)); + symbol = getMergedSymbol(resolveName(location || name, qualifiedNameTextRaw(name), meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true)); if (!symbol) { return getMergedSymbol(symbolFromJSPrototype); } @@ -3079,7 +3079,7 @@ namespace ts { } } } - symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning)); + symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), qualifiedNameTextRaw(right), meaning)); if (!symbol) { if (!ignoreErrors) { const namespaceName = getFullyQualifiedName(namespace); @@ -3108,11 +3108,11 @@ namespace ts { * name resolution won't work either. * 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too. */ - function resolveEntityNameFromAssignmentDeclaration(name: Identifier, meaning: SymbolFlags) { + function resolveEntityNameFromAssignmentDeclaration(name: Identifier | StringLiteralLike, meaning: SymbolFlags) { if (isJSDocTypeReference(name.parent)) { const secondaryLocation = getAssignmentDeclarationLocation(name.parent); if (secondaryLocation) { - return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true); + return resolveName(secondaryLocation, qualifiedNameTextRaw(name), meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true); } } } @@ -4808,16 +4808,7 @@ namespace ts { // first shift type arguments let typeArguments = root.typeArguments; let qualifier = root.qualifier; - if (qualifier) { - if (isIdentifier(qualifier)) { - qualifier = factory.updateIdentifier(qualifier, typeArguments); - } - else { - qualifier = factory.updateQualifiedName(qualifier, - qualifier.left, - factory.updateIdentifier(qualifier.right, typeArguments)); - } - } + qualifier = qualifier ? updateEntityTypeArguments(qualifier, typeArguments) : undefined; typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); @@ -4835,14 +4826,7 @@ namespace ts { // first shift type arguments let typeArguments = root.typeArguments; let typeName = root.typeName; - if (isIdentifier(typeName)) { - typeName = factory.updateIdentifier(typeName, typeArguments); - } - else { - typeName = factory.updateQualifiedName(typeName, - typeName.left, - factory.updateIdentifier(typeName.right, typeArguments)); - } + typeName = updateEntityTypeArguments(typeName, typeArguments); typeArguments = ref.typeArguments; // then move qualifiers const ids = getAccessStack(ref); @@ -4854,12 +4838,27 @@ namespace ts { typeName, typeArguments); } + + function updateEntityTypeArguments(name: EntityName, typeArguments: NodeArray | undefined) { + if (isIdentifier(name)) { + return factory.updateIdentifier(name, typeArguments); + } + if (isStringLiteralLike(name)) { + return name; // TODO ? + } + if (isIdentifier(name.right)) { + return factory.updateQualifiedName(name, + name.left, + factory.updateIdentifier(name.right, typeArguments)); + } + return name; // TODO ? + } } - function getAccessStack(ref: TypeReferenceNode): Identifier[] { + function getAccessStack(ref: TypeReferenceNode): (Identifier | StringLiteralLike)[] { let state = ref.typeName; const ids = []; - while (!isIdentifier(state)) { + while (isQualifiedName(state)) { ids.unshift(state.right); state = state.left; } @@ -5209,7 +5208,7 @@ namespace ts { const dotDotDotToken = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(factory.cloneNode(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : - parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(factory.cloneNode(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? isIdentifier(parameterDeclaration.name.right) ? setEmitFlags(factory.cloneNode(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : symbolName(parameterSymbol) : cloneBindingName(parameterDeclaration.name) : symbolName(parameterSymbol) : symbolName(parameterSymbol); @@ -5469,8 +5468,10 @@ namespace ts { context.approximateLength += specifier.length + 10; // specifier + import("") if (!nonRootParts || isEntityName(nonRootParts)) { if (nonRootParts) { - const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right; - lastId.typeArguments = undefined; + const lastId = isQualifiedName(nonRootParts) ? nonRootParts.right : nonRootParts; + if (isIdentifier(lastId)) { + lastId.typeArguments = undefined; + } } return factory.createImportTypeNode(lit, nonRootParts as EntityName, typeParameterNodes as readonly TypeNode[], isTypeOf); } @@ -5489,9 +5490,11 @@ namespace ts { return factory.createTypeQueryNode(entityName); } else { - const lastId = isIdentifier(entityName) ? entityName : entityName.right; - const lastTypeArgs = lastId.typeArguments; - lastId.typeArguments = undefined; + const lastId = isQualifiedName(entityName) ? entityName.right : entityName; + const lastTypeArgs = isIdentifier(lastId) ? lastId.typeArguments : undefined; + if (isIdentifier(lastId)) { + lastId.typeArguments = undefined; + } return factory.createTypeReferenceNode(entityName, lastTypeArgs as NodeArray); } @@ -5836,12 +5839,12 @@ namespace ts { if (isJSDocTypeLiteral(node)) { return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => { const name = isIdentifier(t.name) ? t.name : t.name.right; - const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText); + const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), qualifiedNameTextRaw(name)); const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined; return factory.createPropertySignature( /*modifiers*/ undefined, - name, + isNoSubstitutionTemplateLiteral(name) ? factory.createLiteralLikeNode(SyntaxKind.StringLiteral, name.text) as StringLiteral : name, t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? factory.createToken(SyntaxKind.QuestionToken) : undefined, overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); @@ -5911,7 +5914,7 @@ namespace ts { ); } - if (isEntityName(node) || isEntityNameExpression(node)) { + if ((isEntityName(node) || isEntityNameExpression(node)) && !isStringLiteralLike(node) && node.parent.kind !== SyntaxKind.ImportType) { const leftmost = getFirstIdentifier(node); if (isInJSFile(node) && (isExportsIdentifier(leftmost) || isModuleExportsAccessExpression(leftmost.parent) || (isQualifiedName(leftmost.parent) && isModuleIdentifier(leftmost.parent.left) && isExportsIdentifier(leftmost.parent.right)))) { hadError = true; @@ -14218,12 +14221,12 @@ namespace ts { return links.resolvedType; } - function getIdentifierChain(node: EntityName): Identifier[] { - if (isIdentifier(node)) { + function getQualifiedNameChain(node: EntityName): (Identifier | StringLiteralLike)[] { + if (!isQualifiedName(node)) { return [node]; } else { - return append(getIdentifierChain(node.left), node.right); + return append(getQualifiedNameChain(node.left), node.right); } } @@ -14249,12 +14252,12 @@ namespace ts { } const moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false); if (!nodeIsMissing(node.qualifier)) { - const nameStack: Identifier[] = getIdentifierChain(node.qualifier!); + const nameStack: (Identifier | StringLiteralLike)[] = getQualifiedNameChain(node.qualifier!); let currentNamespace = moduleSymbol; - let current: Identifier | undefined; + let current: Identifier | StringLiteralLike | undefined; while (current = nameStack.shift()) { const meaning = nameStack.length ? SymbolFlags.Namespace : targetMeaning; - const next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), current.escapedText, meaning); + const next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), qualifiedNameTextRaw(current), meaning); if (!next) { error(current, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), declarationNameToString(current)); return links.resolvedType = errorType; @@ -25503,7 +25506,7 @@ namespace ts { && getThisContainer(node, /*includeArrowFunctions*/ true) === getDeclaringConstructor(prop); } - function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateIdentifier) { + function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateIdentifier | StringLiteralLike) { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); @@ -25536,7 +25539,7 @@ namespace ts { } return apparentType; } - prop = getPropertyOfType(apparentType, right.escapedText); + prop = getPropertyOfType(apparentType, qualifiedNameTextRaw(right)); } if (isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) { markAliasReferenced(parentSymbol, node); @@ -25549,16 +25552,17 @@ namespace ts { if (isJSLiteralType(leftType)) { return anyType; } + const rightText = qualifiedNameTextRaw(right); if (leftType.symbol === globalThisSymbol) { - if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) { - error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(right.escapedText), typeToString(leftType)); + if (globalThisSymbol.exports!.has(rightText) && (globalThisSymbol.exports!.get(rightText)!.flags & SymbolFlags.BlockScoped)) { + error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(rightText), typeToString(leftType)); } else if (noImplicitAny) { error(right, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType)); } return anyType; } - if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { + if (rightText && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType); } return errorType; @@ -25571,7 +25575,7 @@ namespace ts { } else { if (prop.valueDeclaration?.flags & NodeFlags.Deprecated && isUncalledFunctionReference(node, prop)) { - errorOrSuggestion(/* isError */ false, right, Diagnostics._0_is_deprecated, right.escapedText as string); + errorOrSuggestion(/* isError */ false, right, Diagnostics._0_is_deprecated, qualifiedNameText(right)); } checkPropertyNotUsedBeforeDeclaration(prop, node, right); @@ -25579,7 +25583,7 @@ namespace ts { getNodeLinks(node).resolvedSymbol = prop; checkPropertyAccessibility(node, left.kind === SyntaxKind.SuperKeyword, apparentType, prop); if (isAssignmentToReadonlyEntity(node as Expression, prop, assignmentKind)) { - error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, idText(right)); + error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, qualifiedNameText(right)); return errorType; } propType = isThisPropertyAccessInConstructor(node, prop) ? autoType : getConstraintForLocation(getTypeOfSymbol(prop), node); @@ -25629,14 +25633,14 @@ namespace ts { return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } - function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateIdentifier): void { + function checkPropertyNotUsedBeforeDeclaration(prop: Symbol, node: PropertyAccessExpression | QualifiedName, right: Identifier | PrivateIdentifier | StringLiteralLike): void { const { valueDeclaration } = prop; if (!valueDeclaration || getSourceFileOfNode(node).isDeclarationFile) { return; } let diagnosticMessage; - const declarationName = idText(right); + const declarationName = qualifiedNameText(right); if (isInPropertyInitializer(node) && !(isAccessExpression(node) && isAccessExpression(node.expression)) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) @@ -25712,23 +25716,23 @@ namespace ts { return getIntersectionType(x); } - function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type) { + function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier | StringLiteralLike, containingType: Type) { let errorInfo: DiagnosticMessageChain | undefined; let relatedInfo: Diagnostic | undefined; if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { for (const subtype of (containingType as UnionType).types) { - if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, IndexKind.String)) { + if (!getPropertyOfType(subtype, qualifiedNameTextRaw(propNode)) && !getIndexInfoOfType(subtype, IndexKind.String)) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(subtype)); break; } } } - if (typeHasStaticProperty(propNode.escapedText, containingType)) { + if (typeHasStaticProperty(qualifiedNameTextRaw(propNode), containingType)) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_is_a_static_member_of_type_1, declarationNameToString(propNode), typeToString(containingType)); } else { const promisedType = getPromisedTypeOfPromise(containingType); - if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) { + if (promisedType && getPropertyOfType(promisedType, qualifiedNameTextRaw(propNode))) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); relatedInfo = createDiagnosticForNode(propNode, Diagnostics.Did_you_forget_to_use_await); } @@ -25756,8 +25760,8 @@ namespace ts { return prop !== undefined && prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static); } - function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { - return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value); + function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | StringLiteralLike | string, containingType: Type): Symbol | undefined { + return getSpellingSuggestionForName(isString(name) ? name : qualifiedNameText(name), getPropertiesOfType(containingType), SymbolFlags.Value); } function getSuggestedSymbolForNonexistentJSXAttribute(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined { @@ -25792,8 +25796,8 @@ namespace ts { return symbolResult && symbolName(symbolResult); } - function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined { - return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember); + function getSuggestedSymbolForNonexistentModule(name: Identifier | StringLiteralLike, targetModule: Symbol): Symbol | undefined { + return targetModule.exports && getSpellingSuggestionForName(qualifiedNameText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember); } function getSuggestionForNonexistentExport(name: Identifier, targetModule: Symbol): string | undefined { @@ -31487,9 +31491,6 @@ namespace ts { function checkTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments) { checkGrammarTypeArguments(node, node.typeArguments); - if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) { - grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); - } forEach(node.typeArguments, checkSourceElement); const type = getTypeFromTypeReference(node); if (type !== errorType) { @@ -32659,7 +32660,7 @@ namespace ts { !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { error(node.name, Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, - idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); + qualifiedNameText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); } } } @@ -35825,15 +35826,10 @@ namespace ts { } } - function getFirstNonModuleExportsIdentifier(node: EntityNameOrEntityNameExpression): Identifier { + function getFirstNonModuleExportsIdentifier(node: EntityNameExpression): Identifier { switch (node.kind) { case SyntaxKind.Identifier: return node; - case SyntaxKind.QualifiedName: - do { - node = node.left; - } while (node.kind !== SyntaxKind.Identifier); - return node; case SyntaxKind.PropertyAccessExpression: do { if (isModuleExportsAccessExpression(node.expression) && !isPrivateIdentifier(node.name)) { @@ -37046,7 +37042,7 @@ namespace ts { const meaning = name.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; return resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } - else if (isJSDocEntryNameReference(name)) { + else if (!isStringLiteralLike(name) && isJSDocEntryNameReference(name)) { const meaning = SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value; return resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true, getHostSignatureFromJSDoc(name)); } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 3d1b6fdb9a7d3..fc6afc580d03b 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -4218,7 +4218,7 @@ namespace ts { } // @api - function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag { + function createJSDocParameterTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag { const node = createBaseJSDocTag(SyntaxKind.JSDocParameterTag, tagName ?? createIdentifier("param"), comment); node.typeExpression = typeExpression; node.name = name; @@ -4228,7 +4228,7 @@ namespace ts { } // @api - function updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag { + function updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier = getDefaultTagName(node), name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag { return node.tagName !== tagName || node.name !== name || node.isBracketed !== isBracketed @@ -4240,7 +4240,7 @@ namespace ts { } // @api - function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag { + function createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag { const node = createBaseJSDocTag(SyntaxKind.JSDocPropertyTag, tagName ?? createIdentifier("prop"), comment); node.typeExpression = typeExpression; node.name = name; @@ -4250,7 +4250,7 @@ namespace ts { } // @api - function updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier = getDefaultTagName(node), name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag { + function updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier = getDefaultTagName(node), name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag { return node.tagName !== tagName || node.name !== name || node.isBracketed !== isBracketed diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 770600d94b71d..1fe726ec4d317 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -37,12 +37,10 @@ namespace ts { function createJsxFactoryExpressionFromEntityName(factory: NodeFactory, jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { if (isQualifiedName(jsxFactory)) { const left = createJsxFactoryExpressionFromEntityName(factory, jsxFactory.left, parent); - const right = factory.createIdentifier(idText(jsxFactory.right)) as Mutable; - right.escapedText = jsxFactory.right.escapedText; - return factory.createPropertyAccessExpression(left, right); + return isStringLiteralLike(jsxFactory.right) ? factory.createElementAccessExpression(left, factory.createStringLiteral(jsxFactory.right.text)) : factory.createPropertyAccessExpression(left, factory.createIdentifier(idText(jsxFactory.right))); } else { - return createReactNamespace(idText(jsxFactory), parent); + return createReactNamespace(qualifiedNameText(jsxFactory), parent); } } @@ -162,7 +160,7 @@ namespace ts { const left = createExpressionFromEntityName(factory, node.left); // TODO(rbuckton): Does this need to be parented? const right = setParent(setTextRange(factory.cloneNode(node.right), node.right), node.right.parent); - return setTextRange(factory.createPropertyAccessExpression(left, right), node); + return setTextRange(isStringLiteralLike(right) ? factory.createElementAccessExpression(left, right) : factory.createPropertyAccessExpression(left, right), node); } else { // TODO(rbuckton): Does this need to be parented? diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a815a12db9a53..c0a706aabd4a9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2503,21 +2503,23 @@ namespace ts { return createMissingList(); } - function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { + function parseEntityName(allowReservedWords: boolean, allowLeadingLiteral?: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { const pos = getNodePos(); - let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); + let entity: EntityName = (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NoSubstitutionTemplateLiteral) && allowLeadingLiteral ? parseLiteralLikeNode(token()) as StringLiteralLike : allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); let dotPos = getNodePos(); while (parseOptional(SyntaxKind.DotToken)) { if (token() === SyntaxKind.LessThanToken) { - // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting - entity.jsdocDotPos = dotPos; + // the entity is part of a JSDoc-style generic, so report an error + if (!(contextFlags & NodeFlags.JSDoc)) { + parseErrorAt(dotPos, dotPos + 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + } break; } dotPos = getNodePos(); entity = finishNode( factory.createQualifiedName( entity, - parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier + parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false, /*allowStringLike*/ true) ), pos ); @@ -2529,7 +2531,10 @@ namespace ts { return finishNode(factory.createQualifiedName(entity, name), entity.pos); } - function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): Identifier | PrivateIdentifier { + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: true): Identifier | PrivateIdentifier; + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: false): Identifier; + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: false, allowStringLike: true): Identifier | StringLiteralLike; + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean, allowStringLike?: boolean): Identifier | PrivateIdentifier | StringLiteralLike { // Technically a keyword is valid here as all identifiers and keywords are identifier names. // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. @@ -2565,6 +2570,10 @@ namespace ts { return allowPrivateIdentifiers ? node : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); } + if (allowStringLike && token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NoSubstitutionTemplateLiteral) { + return parseLiteralLikeNode(token()) as StringLiteralLike; + } + return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); } @@ -2701,8 +2710,8 @@ namespace ts { // TYPES - function parseEntityNameOfTypeReference() { - return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); + function parseEntityNameOfTypeReference(allowLeadingLiteral?: boolean) { + return parseEntityName(/*allowReservedWords*/ true, allowLeadingLiteral, Diagnostics.Type_expected); } function parseTypeArgumentsOfTypeReference() { @@ -3413,7 +3422,7 @@ namespace ts { parseExpected(SyntaxKind.OpenParenToken); const type = parseType(); parseExpected(SyntaxKind.CloseParenToken); - const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; + const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference(/*allowLeadingLiteral*/ true) : undefined; const typeArguments = parseTypeArgumentsOfTypeReference(); return finishNode(factory.createImportTypeNode(type, qualifier, typeArguments, isTypeOf), pos); } @@ -7630,7 +7639,7 @@ namespace ts { return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; } - function parseBracketNameInPropertyAndParamTag(): { name: EntityName, isBracketed: boolean } { + function parseBracketNameInPropertyAndParamTag(): { name: EntityNameNoRootLiteral, isBracketed: boolean } { // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); if (isBracketed) { @@ -7965,8 +7974,8 @@ namespace ts { } function escapedTextsEqual(a: EntityName, b: EntityName): boolean { - while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) { - if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) { + while (isQualifiedName(a) || isQualifiedName(b)) { + if (isQualifiedName(a) && isQualifiedName(b) && qualifiedNameTextRaw(a.right) === qualifiedNameTextRaw(b.right)) { a = a.left; b = b.left; } @@ -7974,7 +7983,7 @@ namespace ts { return false; } } - return a.escapedText === b.escapedText; + return qualifiedNameTextRaw(a) === qualifiedNameTextRaw(b); } function parseChildPropertyTag(indent: number) { @@ -8089,8 +8098,8 @@ namespace ts { return false; } - function parseJSDocEntityName(): EntityName { - let entity: EntityName = parseJSDocIdentifierName(); + function parseJSDocEntityName(): EntityNameNoRootLiteral { + let entity: EntityNameNoRootLiteral = parseJSDocIdentifierName(); if (parseOptional(SyntaxKind.OpenBracketToken)) { parseExpected(SyntaxKind.CloseBracketToken); // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 3e2e789259915..fb0ef800bed9c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1387,7 +1387,7 @@ namespace ts { return false; } - type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression; + type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression | ElementAccessExpression; type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression; function getAccessorTypeNode(node: AccessorDeclaration) { @@ -1730,6 +1730,9 @@ namespace ts { const copied = serializeEntityNameAsExpression(node); return createCheckedValue(copied, copied); } + if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral) { + return Debug.failBadSyntaxKind(node); + } if (node.left.kind === SyntaxKind.Identifier) { // A.B -> typeof A !== undefined && A.B return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node)); @@ -1742,7 +1745,7 @@ namespace ts { left.left, factory.createStrictInequality(factory.createAssignment(temp, left.right), factory.createVoidZero()) ), - factory.createPropertyAccessExpression(temp, node.right) + isStringLiteralLike(node.right) ? factory.createElementAccessExpression(temp, factory.createStringLiteral(node.right.text)) : factory.createPropertyAccessExpression(temp, node.right) ); } @@ -1763,6 +1766,10 @@ namespace ts { case SyntaxKind.QualifiedName: return serializeQualifiedNameAsExpression(node); + + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + return Debug.failBadSyntaxKind(node); } } @@ -1774,7 +1781,9 @@ namespace ts { * qualified name at runtime. */ function serializeQualifiedNameAsExpression(node: QualifiedName): SerializedEntityNameAsExpression { - return factory.createPropertyAccessExpression(serializeEntityNameAsExpression(node.left), node.right); + return isStringLiteralLike(node.right) + ? factory.createElementAccessExpression(serializeEntityNameAsExpression(node.left), factory.createStringLiteral(node.right.text)) + : factory.createPropertyAccessExpression(serializeEntityNameAsExpression(node.left), node.right); } /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fbf308707a10d..a85d531cd4f61 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1094,7 +1094,6 @@ namespace ts { /*@internal*/ generatedImportReference?: ImportSpecifier; // Reference to the generated import specifier this identifier refers to isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. - /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. } // Transient identifier node (marked by id === -1) @@ -1110,11 +1109,12 @@ namespace ts { export interface QualifiedName extends Node { readonly kind: SyntaxKind.QualifiedName; readonly left: EntityName; - readonly right: Identifier; - /*@internal*/ jsdocDotPos?: number; // QualifiedName occurs in JSDoc-style generic: Id1.Id2. + readonly right: Identifier | StringLiteralLike; } - export type EntityName = Identifier | QualifiedName; + export type EntityName = Identifier | QualifiedName | StringLiteralLike; + + export type EntityNameNoRootLiteral = Identifier | QualifiedName; export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; @@ -3249,7 +3249,7 @@ namespace ts { export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { readonly parent: JSDoc; - readonly name: EntityName; + readonly name: EntityNameNoRootLiteral; readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ readonly isNameFirst: boolean; @@ -4054,7 +4054,7 @@ namespace ts { /* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined; /* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined; /* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined; - /* @internal */ getSuggestedSymbolForNonexistentModule(node: Identifier, target: Symbol): Symbol | undefined; + /* @internal */ getSuggestedSymbolForNonexistentModule(node: Identifier | StringLiteralLike, target: Symbol): Symbol | undefined; /* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined; getBaseConstraintOfType(type: Type): Type | undefined; getDefaultFromTypeParameter(type: Type): Type | undefined; @@ -6724,8 +6724,8 @@ namespace ts { // Names // - createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; - updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createQualifiedName(left: EntityName, right: string | Identifier | StringLiteralLike): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier | StringLiteralLike): QualifiedName; createComputedPropertyName(expression: Expression): ComputedPropertyName; updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; @@ -7041,10 +7041,10 @@ namespace ts { updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; - createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; - updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; - createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; - updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; createJSDocSeeTag(tagName: Identifier | undefined, nameExpression: JSDocNameReference | undefined, comment?: string): JSDocSeeTag; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 973528096a1f3..1fb328e19afc6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -890,10 +890,14 @@ namespace ts { } } - export function entityNameToString(name: EntityNameOrEntityNameExpression | JsxTagNameExpression | PrivateIdentifier): string { + export function entityNameToString(name: EntityNameOrEntityNameExpression | JsxTagNameExpression | PrivateIdentifier | StringLiteralLike): string { switch (name.kind) { case SyntaxKind.ThisKeyword: return "this"; + case SyntaxKind.StringLiteral: + return name.singleQuote ? `'${escapeString(name.text, CharacterCodes.singleQuote)}'` : `"${escapeString(name.text, CharacterCodes.doubleQuote)}"`; + case SyntaxKind.NoSubstitutionTemplateLiteral: + return `\`${escapeString(name.text, CharacterCodes.backtick)}\``; case SyntaxKind.PrivateIdentifier: case SyntaxKind.Identifier: return getFullWidth(name) === 0 ? idText(name) : getTextOfNode(name); @@ -4760,13 +4764,17 @@ namespace ts { case SyntaxKind.QualifiedName: do { node = node.left; - } while (node.kind !== SyntaxKind.Identifier); + } while (node.kind === SyntaxKind.QualifiedName); + Debug.assertNode(node, isIdentifier); // The only leftmost qualified name that's not identifier is import type node leftmost names return node; case SyntaxKind.PropertyAccessExpression: do { node = node.expression; } while (node.kind !== SyntaxKind.Identifier); return node; + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + return Debug.failBadSyntaxKind(node); } } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index e9d28e8fab5c1..e4f92527ed252 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -467,6 +467,12 @@ namespace ts { } return unescapeLeadingUnderscores(symbol.escapedName); } + export function qualifiedNameTextRaw(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): __String { + return isIdentifier(identifierOrString) || isPrivateIdentifier(identifierOrString) ? identifierOrString.escapedText : escapeLeadingUnderscores(identifierOrString.text); + } + export function qualifiedNameText(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): string { + return isIdentifier(identifierOrString) || isPrivateIdentifier(identifierOrString) ? idText(identifierOrString) : identifierOrString.text; + } /** * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should @@ -1151,7 +1157,9 @@ namespace ts { export function isEntityName(node: Node): node is EntityName { const kind = node.kind; return kind === SyntaxKind.QualifiedName - || kind === SyntaxKind.Identifier; + || kind === SyntaxKind.Identifier + || kind === SyntaxKind.StringLiteral + || kind === SyntaxKind.NoSubstitutionTemplateLiteral; } export function isPropertyName(node: Node): node is PropertyName { diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 3c5669cb20c58..b0c6157bb42e0 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -482,7 +482,7 @@ namespace ts.codefix { } function replaceFirstIdentifierOfEntityName(name: EntityName, newIdentifier: Identifier): EntityName { - if (name.kind === SyntaxKind.Identifier) { + if (name.kind !== SyntaxKind.QualifiedName) { return newIdentifier; } return factory.createQualifiedName(replaceFirstIdentifierOfEntityName(name.left, newIdentifier), name.right); diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts index bf89394118798..6e3667cc4295d 100644 --- a/src/services/refactors/extractType.ts +++ b/src/services/refactors/extractType.ts @@ -158,7 +158,7 @@ namespace ts.refactor { } } else if (isTypeQueryNode(node)) { - if (isIdentifier(node.exprName)) { + if (!isQualifiedName(node.exprName)) { const symbol = checker.resolveName(node.exprName.text, node.exprName, SymbolFlags.Value, /* excludeGlobals */ false); if (symbol && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) { return true; diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json index cfbef060a8516..b1778ff786534 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference1.json @@ -12,8 +12,7 @@ "flags": "JSDoc", "modifierFlagsCache": 0, "transformFlags": 0, - "escapedText": "a", - "jsdocDotPos": 2 + "escapedText": "a" }, "typeArguments": { "0": { diff --git a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json index 3802cb3212932..8ac51a4783083 100644 --- a/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json +++ b/tests/baselines/reference/JSDocParsing/TypeExpressions.parsesCorrectly.typeReference2.json @@ -12,8 +12,7 @@ "flags": "JSDoc", "modifierFlagsCache": 0, "transformFlags": 0, - "escapedText": "a", - "jsdocDotPos": 2 + "escapedText": "a" }, "typeArguments": { "0": { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2b5ca8d1f18f6..96d59ab37ba07 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -634,9 +634,10 @@ declare namespace ts { export interface QualifiedName extends Node { readonly kind: SyntaxKind.QualifiedName; readonly left: EntityName; - readonly right: Identifier; + readonly right: Identifier | StringLiteralLike; } - export type EntityName = Identifier | QualifiedName; + export type EntityName = Identifier | QualifiedName | StringLiteralLike; + export type EntityNameNoRootLiteral = Identifier | QualifiedName; export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { @@ -1836,7 +1837,7 @@ declare namespace ts { } export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { readonly parent: JSDoc; - readonly name: EntityName; + readonly name: EntityNameNoRootLiteral; readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ readonly isNameFirst: boolean; @@ -3188,8 +3189,8 @@ declare namespace ts { createFalse(): FalseLiteral; createModifier(kind: T): ModifierToken; createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; - createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; - updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createQualifiedName(left: EntityName, right: string | Identifier | StringLiteralLike): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier | StringLiteralLike): QualifiedName; createComputedPropertyName(expression: Expression): ComputedPropertyName; updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; @@ -3455,10 +3456,10 @@ declare namespace ts { updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; - createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; - updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; - createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; - updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; createJSDocSeeTag(tagName: Identifier | undefined, nameExpression: JSDocNameReference | undefined, comment?: string): JSDocSeeTag; @@ -4082,6 +4083,8 @@ declare namespace ts { function unescapeLeadingUnderscores(identifier: __String): string; function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string; function symbolName(symbol: Symbol): string; + function qualifiedNameTextRaw(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): __String; + function qualifiedNameText(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): string; function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** @@ -10086,9 +10089,9 @@ declare namespace ts { /** @deprecated Use `factory.createModifiersFromModifierFlags` or the factory supplied by your transformation context instead. */ const createModifiersFromModifierFlags: (flags: ModifierFlags) => Modifier[]; /** @deprecated Use `factory.createQualifiedName` or the factory supplied by your transformation context instead. */ - const createQualifiedName: (left: EntityName, right: string | Identifier) => QualifiedName; + const createQualifiedName: (left: EntityName, right: string | Identifier | StringLiteral | NoSubstitutionTemplateLiteral) => QualifiedName; /** @deprecated Use `factory.updateQualifiedName` or the factory supplied by your transformation context instead. */ - const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier) => QualifiedName; + const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier | StringLiteral | NoSubstitutionTemplateLiteral) => QualifiedName; /** @deprecated Use `factory.createComputedPropertyName` or the factory supplied by your transformation context instead. */ const createComputedPropertyName: (expression: Expression) => ComputedPropertyName; /** @deprecated Use `factory.updateComputedPropertyName` or the factory supplied by your transformation context instead. */ @@ -10142,7 +10145,7 @@ declare namespace ts { /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ const updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; /** @deprecated Use `factory.createTypeReferenceNode` or the factory supplied by your transformation context instead. */ - const createTypeReferenceNode: (typeName: string | Identifier | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; + const createTypeReferenceNode: (typeName: string | Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; /** @deprecated Use `factory.updateTypeReferenceNode` or the factory supplied by your transformation context instead. */ const updateTypeReferenceNode: (node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) => TypeReferenceNode; /** @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ @@ -10194,9 +10197,9 @@ declare namespace ts { /** @deprecated Use `factory.updateInferTypeNode` or the factory supplied by your transformation context instead. */ const updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) => InferTypeNode; /** @deprecated Use `factory.createImportTypeNode` or the factory supplied by your transformation context instead. */ - const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; /** @deprecated Use `factory.updateImportTypeNode` or the factory supplied by your transformation context instead. */ - const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; /** @deprecated Use `factory.createParenthesizedType` or the factory supplied by your transformation context instead. */ const createParenthesizedType: (type: TypeNode) => ParenthesizedTypeNode; /** @deprecated Use `factory.updateParenthesizedType` or the factory supplied by your transformation context instead. */ @@ -10522,7 +10525,7 @@ declare namespace ts { /** @deprecated Use `factory.createJSDocComment` or the factory supplied by your transformation context instead. */ const createJSDocComment: (comment?: string | undefined, tags?: readonly JSDocTag[] | undefined) => JSDoc; /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ - const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; + const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; /** @deprecated Use `factory.createJSDocClassTag` or the factory supplied by your transformation context instead. */ const createJSDocClassTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocClassTag; /** @deprecated Use `factory.createJSDocAugmentsTag` or the factory supplied by your transformation context instead. */ @@ -10540,7 +10543,7 @@ declare namespace ts { /** @deprecated Use `factory.createJSDocSignature` or the factory supplied by your transformation context instead. */ const createJSDocSignature: (typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag | undefined) => JSDocSignature; /** @deprecated Use `factory.createJSDocPropertyTag` or the factory supplied by your transformation context instead. */ - const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; + const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; /** @deprecated Use `factory.createJSDocTypeLiteral` or the factory supplied by your transformation context instead. */ const createJSDocTypeLiteral: (jsDocPropertyTags?: readonly JSDocPropertyLikeTag[] | undefined, isArrayType?: boolean | undefined) => JSDocTypeLiteral; /** @deprecated Use `factory.createJSDocImplementsTag` or the factory supplied by your transformation context instead. */ @@ -10768,7 +10771,7 @@ declare namespace ts { /** @deprecated Use `factory.updateExportDeclaration` or the factory supplied by your transformation context instead. */ const updateExportDeclaration: (node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean) => ExportDeclaration; /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ - const createJSDocParamTag: (name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; + const createJSDocParamTag: (name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; /** @deprecated Use `factory.createComma` or the factory supplied by your transformation context instead. */ const createComma: (left: Expression, right: Expression) => Expression; /** @deprecated Use `factory.createLessThan` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0df67772e6e09..23dadc9fa1528 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -634,9 +634,10 @@ declare namespace ts { export interface QualifiedName extends Node { readonly kind: SyntaxKind.QualifiedName; readonly left: EntityName; - readonly right: Identifier; + readonly right: Identifier | StringLiteralLike; } - export type EntityName = Identifier | QualifiedName; + export type EntityName = Identifier | QualifiedName | StringLiteralLike; + export type EntityNameNoRootLiteral = Identifier | QualifiedName; export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier; export type DeclarationName = Identifier | PrivateIdentifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | ElementAccessExpression | BindingPattern | EntityNameExpression; export interface Declaration extends Node { @@ -1836,7 +1837,7 @@ declare namespace ts { } export interface JSDocPropertyLikeTag extends JSDocTag, Declaration { readonly parent: JSDoc; - readonly name: EntityName; + readonly name: EntityNameNoRootLiteral; readonly typeExpression?: JSDocTypeExpression; /** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */ readonly isNameFirst: boolean; @@ -3188,8 +3189,8 @@ declare namespace ts { createFalse(): FalseLiteral; createModifier(kind: T): ModifierToken; createModifiersFromModifierFlags(flags: ModifierFlags): Modifier[]; - createQualifiedName(left: EntityName, right: string | Identifier): QualifiedName; - updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName; + createQualifiedName(left: EntityName, right: string | Identifier | StringLiteralLike): QualifiedName; + updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier | StringLiteralLike): QualifiedName; createComputedPropertyName(expression: Expression): ComputedPropertyName; updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName; createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode): TypeParameterDeclaration; @@ -3455,10 +3456,10 @@ declare namespace ts { updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier | undefined, constraint: JSDocTypeExpression | undefined, typeParameters: readonly TypeParameterDeclaration[], comment: string | undefined): JSDocTemplateTag; createJSDocTypedefTag(tagName: Identifier | undefined, typeExpression?: JSDocTypeExpression | JSDocTypeLiteral, fullName?: Identifier | JSDocNamespaceDeclaration, comment?: string): JSDocTypedefTag; updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined, fullName: Identifier | JSDocNamespaceDeclaration | undefined, comment: string | undefined): JSDocTypedefTag; - createJSDocParameterTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; - updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; - createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; - updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; + createJSDocParameterTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocParameterTag; + updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocParameterTag; + createJSDocPropertyTag(tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression, isNameFirst?: boolean, comment?: string): JSDocPropertyTag; + updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression: JSDocTypeExpression | undefined, isNameFirst: boolean, comment: string | undefined): JSDocPropertyTag; createJSDocTypeTag(tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment?: string): JSDocTypeTag; updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression, comment: string | undefined): JSDocTypeTag; createJSDocSeeTag(tagName: Identifier | undefined, nameExpression: JSDocNameReference | undefined, comment?: string): JSDocSeeTag; @@ -4082,6 +4083,8 @@ declare namespace ts { function unescapeLeadingUnderscores(identifier: __String): string; function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string; function symbolName(symbol: Symbol): string; + function qualifiedNameTextRaw(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): __String; + function qualifiedNameText(identifierOrString: Identifier | PrivateIdentifier | StringLiteralLike): string; function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined; function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** @@ -6460,9 +6463,9 @@ declare namespace ts { /** @deprecated Use `factory.createModifiersFromModifierFlags` or the factory supplied by your transformation context instead. */ const createModifiersFromModifierFlags: (flags: ModifierFlags) => Modifier[]; /** @deprecated Use `factory.createQualifiedName` or the factory supplied by your transformation context instead. */ - const createQualifiedName: (left: EntityName, right: string | Identifier) => QualifiedName; + const createQualifiedName: (left: EntityName, right: string | Identifier | StringLiteral | NoSubstitutionTemplateLiteral) => QualifiedName; /** @deprecated Use `factory.updateQualifiedName` or the factory supplied by your transformation context instead. */ - const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier) => QualifiedName; + const updateQualifiedName: (node: QualifiedName, left: EntityName, right: Identifier | StringLiteral | NoSubstitutionTemplateLiteral) => QualifiedName; /** @deprecated Use `factory.createComputedPropertyName` or the factory supplied by your transformation context instead. */ const createComputedPropertyName: (expression: Expression) => ComputedPropertyName; /** @deprecated Use `factory.updateComputedPropertyName` or the factory supplied by your transformation context instead. */ @@ -6516,7 +6519,7 @@ declare namespace ts { /** @deprecated Use `factory.updateTypePredicateNode` or the factory supplied by your transformation context instead. */ const updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) => TypePredicateNode; /** @deprecated Use `factory.createTypeReferenceNode` or the factory supplied by your transformation context instead. */ - const createTypeReferenceNode: (typeName: string | Identifier | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; + const createTypeReferenceNode: (typeName: string | Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName, typeArguments?: readonly TypeNode[] | undefined) => TypeReferenceNode; /** @deprecated Use `factory.updateTypeReferenceNode` or the factory supplied by your transformation context instead. */ const updateTypeReferenceNode: (node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) => TypeReferenceNode; /** @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ @@ -6568,9 +6571,9 @@ declare namespace ts { /** @deprecated Use `factory.updateInferTypeNode` or the factory supplied by your transformation context instead. */ const updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) => InferTypeNode; /** @deprecated Use `factory.createImportTypeNode` or the factory supplied by your transformation context instead. */ - const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + const createImportTypeNode: (argument: TypeNode, qualifier?: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName | undefined, typeArguments?: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; /** @deprecated Use `factory.updateImportTypeNode` or the factory supplied by your transformation context instead. */ - const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; + const updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: Identifier | StringLiteral | NoSubstitutionTemplateLiteral | QualifiedName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean | undefined) => ImportTypeNode; /** @deprecated Use `factory.createParenthesizedType` or the factory supplied by your transformation context instead. */ const createParenthesizedType: (type: TypeNode) => ParenthesizedTypeNode; /** @deprecated Use `factory.updateParenthesizedType` or the factory supplied by your transformation context instead. */ @@ -6896,7 +6899,7 @@ declare namespace ts { /** @deprecated Use `factory.createJSDocComment` or the factory supplied by your transformation context instead. */ const createJSDocComment: (comment?: string | undefined, tags?: readonly JSDocTag[] | undefined) => JSDoc; /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ - const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; + const createJSDocParameterTag: (tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocParameterTag; /** @deprecated Use `factory.createJSDocClassTag` or the factory supplied by your transformation context instead. */ const createJSDocClassTag: (tagName: Identifier | undefined, comment?: string | undefined) => JSDocClassTag; /** @deprecated Use `factory.createJSDocAugmentsTag` or the factory supplied by your transformation context instead. */ @@ -6914,7 +6917,7 @@ declare namespace ts { /** @deprecated Use `factory.createJSDocSignature` or the factory supplied by your transformation context instead. */ const createJSDocSignature: (typeParameters: readonly JSDocTemplateTag[] | undefined, parameters: readonly JSDocParameterTag[], type?: JSDocReturnTag | undefined) => JSDocSignature; /** @deprecated Use `factory.createJSDocPropertyTag` or the factory supplied by your transformation context instead. */ - const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; + const createJSDocPropertyTag: (tagName: Identifier | undefined, name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, isNameFirst?: boolean | undefined, comment?: string | undefined) => JSDocPropertyTag; /** @deprecated Use `factory.createJSDocTypeLiteral` or the factory supplied by your transformation context instead. */ const createJSDocTypeLiteral: (jsDocPropertyTags?: readonly JSDocPropertyLikeTag[] | undefined, isArrayType?: boolean | undefined) => JSDocTypeLiteral; /** @deprecated Use `factory.createJSDocImplementsTag` or the factory supplied by your transformation context instead. */ @@ -7142,7 +7145,7 @@ declare namespace ts { /** @deprecated Use `factory.updateExportDeclaration` or the factory supplied by your transformation context instead. */ const updateExportDeclaration: (node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean) => ExportDeclaration; /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ - const createJSDocParamTag: (name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; + const createJSDocParamTag: (name: EntityNameNoRootLiteral, isBracketed: boolean, typeExpression?: JSDocTypeExpression | undefined, comment?: string | undefined) => JSDocParameterTag; /** @deprecated Use `factory.createComma` or the factory supplied by your transformation context instead. */ const createComma: (left: Expression, right: Expression) => Expression; /** @deprecated Use `factory.createLessThan` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt index cab500645fa4a..e42caf07c5dbe 100644 --- a/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt +++ b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt @@ -1,75 +1,39 @@ tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(2,15): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(4,15): error TS8020: JSDoc types can only be used inside documentation comments. tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(4,32): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(7,20): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(10,18): error TS8020: JSDoc types can only be used inside documentation comments. tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(11,18): error TS2554: Expected 1 arguments, but got 2. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(13,14): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(14,11): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(15,8): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(16,11): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(17,17): error TS8020: JSDoc types can only be used inside documentation comments. tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(18,5): error TS2322: Type 'undefined' is not assignable to type 'number | null'. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(18,17): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(20,16): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(21,16): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(22,17): error TS8020: JSDoc types can only be used inside documentation comments. -==== tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts (16 errors) ==== +==== tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts (4 errors) ==== // grammar error from checker var ara: Array. = [1,2,3]; ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. function f(x: ?number, y: Array.) { - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. return x ? x + y[1] : y[0]; } function hof(ctor: function(new: number, string)) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. return new ctor('hi'); } function hof2(f: function(this: number, string): string) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. return f(12, 'hullo'); ~~~~~~~ !!! error TS2554: Expected 1 arguments, but got 2. } var whatevs: * = 1001; - ~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var ques: ? = 'what'; - ~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var g: function(number, number): number = (n,m) => n + m; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var most: !string = 'definite'; - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var postfixdef: number! = 101; - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var postfixopt: number? = undefined; ~~~~~~~~~~ !!! error TS2322: Type 'undefined' is not assignable to type 'number | null'. - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var nns: Array; - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var dns: Array; - ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. var anys: Array<*>; - ~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. \ No newline at end of file diff --git a/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.js b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.js new file mode 100644 index 0000000000000..ec1f871385adb --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/types/namedTypes/nonIdentifierNamedDirectExportsReferencable.ts] //// + +//// [export.js] +exports["a thing"] = class { + a; + b; +} +//// [usage.ts] +import * as ns from "./export"; + +export const instance: ns."a thing" = new ns["a thing"](); + +//// [export.js] +exports["a thing"] = /** @class */ (function () { + function class_1() { + } + return class_1; +}()); +//// [usage.js] +"use strict"; +exports.__esModule = true; +exports.instance = void 0; +var ns = require("./export"); +exports.instance = new ns["a thing"](); diff --git a/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.symbols b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.symbols new file mode 100644 index 0000000000000..0f23c5c89fccf --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/namedTypes/export.js === +exports["a thing"] = class { +>exports : Symbol("tests/cases/conformance/types/namedTypes/export", Decl(export.js, 0, 0)) +>"a thing" : Symbol("a thing", Decl(export.js, 0, 0)) + + a; +>a : Symbol("a thing".a, Decl(export.js, 0, 28)) + + b; +>b : Symbol("a thing".b, Decl(export.js, 1, 6)) +} +=== tests/cases/conformance/types/namedTypes/usage.ts === +import * as ns from "./export"; +>ns : Symbol(ns, Decl(usage.ts, 0, 6)) + +export const instance: ns."a thing" = new ns["a thing"](); +>instance : Symbol(instance, Decl(usage.ts, 2, 12)) +>ns : Symbol(ns, Decl(usage.ts, 0, 6)) +>ns : Symbol(ns, Decl(usage.ts, 0, 6)) +>"a thing" : Symbol(ns["a thing"], Decl(export.js, 0, 0)) + diff --git a/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.types b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.types new file mode 100644 index 0000000000000..55f0d723f6c9e --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedDirectExportsReferencable.types @@ -0,0 +1,26 @@ +=== tests/cases/conformance/types/namedTypes/export.js === +exports["a thing"] = class { +>exports["a thing"] = class { a; b;} : typeof "a thing" +>exports["a thing"] : typeof "a thing" +>exports : typeof import("tests/cases/conformance/types/namedTypes/export") +>"a thing" : "a thing" +>class { a; b;} : typeof "a thing" + + a; +>a : any + + b; +>b : any +} +=== tests/cases/conformance/types/namedTypes/usage.ts === +import * as ns from "./export"; +>ns : typeof ns + +export const instance: ns."a thing" = new ns["a thing"](); +>instance : ns."a thing" +>ns : any +>new ns["a thing"]() : ns."a thing" +>ns["a thing"] : typeof ns."a thing" +>ns : typeof ns +>"a thing" : "a thing" + diff --git a/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.js b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.js new file mode 100644 index 0000000000000..fe67d333f13bf --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/types/namedTypes/nonIdentifierNamedExportsReferenceable.ts] //// + +//// [a.ts] +export enum Foo { + "1-1", + "1-2" +} +//// [b.ts] +import {Foo} from "./a"; + +export type FooFirst = Foo."1-1"; + +export type FirstFoo = import("./a").Foo."1-1"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; +exports.Foo = void 0; +var Foo; +(function (Foo) { + Foo[Foo["1-1"] = 0] = "1-1"; + Foo[Foo["1-2"] = 1] = "1-2"; +})(Foo = exports.Foo || (exports.Foo = {})); +//// [b.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.symbols b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.symbols new file mode 100644 index 0000000000000..b15e111c73f68 --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.symbols @@ -0,0 +1,22 @@ +=== tests/cases/conformance/types/namedTypes/a.ts === +export enum Foo { +>Foo : Symbol(Foo, Decl(a.ts, 0, 0)) + + "1-1", +>"1-1" : Symbol(Foo["1-1"], Decl(a.ts, 0, 17)) + + "1-2" +>"1-2" : Symbol(Foo["1-2"], Decl(a.ts, 1, 10)) +} +=== tests/cases/conformance/types/namedTypes/b.ts === +import {Foo} from "./a"; +>Foo : Symbol(Foo, Decl(b.ts, 0, 8)) + +export type FooFirst = Foo."1-1"; +>FooFirst : Symbol(FooFirst, Decl(b.ts, 0, 24)) +>Foo : Symbol(Foo, Decl(b.ts, 0, 8)) + +export type FirstFoo = import("./a").Foo."1-1"; +>FirstFoo : Symbol(FirstFoo, Decl(b.ts, 2, 33)) +>Foo : Symbol(Foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.types b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.types new file mode 100644 index 0000000000000..c6b813040a1cc --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedExportsReferenceable.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/types/namedTypes/a.ts === +export enum Foo { +>Foo : Foo + + "1-1", +>"1-1" : Foo.1-1 + + "1-2" +>"1-2" : Foo.1-2 +} +=== tests/cases/conformance/types/namedTypes/b.ts === +import {Foo} from "./a"; +>Foo : typeof Foo + +export type FooFirst = Foo."1-1"; +>FooFirst : Foo.1-1 +>Foo : any + +export type FirstFoo = import("./a").Foo."1-1"; +>FirstFoo : Foo.1-1 +>Foo : any + diff --git a/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.js b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.js new file mode 100644 index 0000000000000..0a1d91e2c048b --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.js @@ -0,0 +1,51 @@ +//// [tests/cases/conformance/types/namedTypes/nonIdentifierNamedLocalImportAlias.ts] //// + +//// [export.js] +exports["another one"] = class { + c; + d; +}; +exports["a thing"] = exports; +//// [usage.ts] +import * as A from "./export"; +import Result = A."a thing"; + +export const another: Result."another one" = new Result["another one"](); +export const again: A."a thing"."a thing"."another one" = null as any as A."another one"; +export const type: typeof Result."a thing"."another one" = {} as any; + +import Result2 = A.'a thing'; + +export const another2: Result.'another one' = new Result['another one'](); +export const again2: A.'a thing'.'a thing'.'another one' = null as any as A.'another one'; +export const type2: typeof Result.'a thing'.'another one' = {} as any; + +import Result3 = A.`a thing`; + +export const another3: Result.`another one` = new Result[`another one`](); +export const again3: A.`a thing`.`a thing`.`another one` = null as any as A.`another one`; +export const type3: typeof Result.`a thing`.`another one` = {} as any; + + +//// [export.js] +exports["another one"] = /** @class */ (function () { + function class_1() { + } + return class_1; +}()); +exports["a thing"] = exports; +//// [usage.js] +"use strict"; +exports.__esModule = true; +exports.type3 = exports.again3 = exports.another3 = exports.type2 = exports.again2 = exports.another2 = exports.type = exports.again = exports.another = void 0; +var A = require("./export"); +var Result = A["a thing"]; +exports.another = new Result["another one"](); +exports.again = null; +exports.type = {}; +exports.another2 = new Result['another one'](); +exports.again2 = null; +exports.type2 = {}; +exports.another3 = new Result["another one"](); +exports.again3 = null; +exports.type3 = {}; diff --git a/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.symbols b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.symbols new file mode 100644 index 0000000000000..4ea21dcc89fdb --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.symbols @@ -0,0 +1,84 @@ +=== tests/cases/conformance/types/namedTypes/export.js === +exports["another one"] = class { +>exports : Symbol("a thing", Decl(export.js, 0, 0)) +>"another one" : Symbol("another one", Decl(export.js, 0, 0)) + + c; +>c : Symbol("another one".c, Decl(export.js, 0, 32)) + + d; +>d : Symbol("another one".d, Decl(export.js, 1, 6)) + +}; +exports["a thing"] = exports; +>exports : Symbol("a thing", Decl(export.js, 0, 0)) +>"a thing" : Symbol("a thing", Decl(export.js, 3, 2)) +>exports : Symbol("a thing", Decl(export.js, 0, 0)) + +=== tests/cases/conformance/types/namedTypes/usage.ts === +import * as A from "./export"; +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +import Result = A."a thing"; +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const another: Result."another one" = new Result["another one"](); +>another : Symbol(another, Decl(usage.ts, 3, 12)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>"another one" : Symbol(A["another one"], Decl(export.js, 0, 0)) + +export const again: A."a thing"."a thing"."another one" = null as any as A."another one"; +>again : Symbol(again, Decl(usage.ts, 4, 12)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const type: typeof Result."a thing"."another one" = {} as any; +>type : Symbol(type, Decl(usage.ts, 5, 12)) +>Result."a thing"."another one" : Symbol(A["another one"], Decl(export.js, 0, 0)) +>Result."a thing" : Symbol(A["a thing"], Decl(export.js, 3, 2)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) + +import Result2 = A.'a thing'; +>Result2 : Symbol(Result2, Decl(usage.ts, 5, 69)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const another2: Result.'another one' = new Result['another one'](); +>another2 : Symbol(another2, Decl(usage.ts, 9, 12)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>'another one' : Symbol(A["another one"], Decl(export.js, 0, 0)) + +export const again2: A.'a thing'.'a thing'.'another one' = null as any as A.'another one'; +>again2 : Symbol(again2, Decl(usage.ts, 10, 12)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const type2: typeof Result.'a thing'.'another one' = {} as any; +>type2 : Symbol(type2, Decl(usage.ts, 11, 12)) +>Result.'a thing'.'another one' : Symbol(A["another one"], Decl(export.js, 0, 0)) +>Result.'a thing' : Symbol(A["a thing"], Decl(export.js, 3, 2)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) + +import Result3 = A.`a thing`; +>Result3 : Symbol(Result3, Decl(usage.ts, 11, 70)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const another3: Result.`another one` = new Result[`another one`](); +>another3 : Symbol(another3, Decl(usage.ts, 15, 12)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) +>`another one` : Symbol(A["another one"], Decl(export.js, 0, 0)) + +export const again3: A.`a thing`.`a thing`.`another one` = null as any as A.`another one`; +>again3 : Symbol(again3, Decl(usage.ts, 16, 12)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) +>A : Symbol(A, Decl(usage.ts, 0, 6)) + +export const type3: typeof Result.`a thing`.`another one` = {} as any; +>type3 : Symbol(type3, Decl(usage.ts, 17, 12)) +>Result.`a thing`.`another one` : Symbol(A["another one"], Decl(export.js, 0, 0)) +>Result.`a thing` : Symbol(A["a thing"], Decl(export.js, 3, 2)) +>Result : Symbol(Result, Decl(usage.ts, 0, 30)) + diff --git a/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.types b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.types new file mode 100644 index 0000000000000..345b2c483a8a3 --- /dev/null +++ b/tests/baselines/reference/nonIdentifierNamedLocalImportAlias.types @@ -0,0 +1,116 @@ +=== tests/cases/conformance/types/namedTypes/export.js === +exports["another one"] = class { +>exports["another one"] = class { c; d;} : typeof "another one" +>exports["another one"] : typeof "another one" +>exports : typeof "a thing" +>"another one" : "another one" +>class { c; d;} : typeof "another one" + + c; +>c : any + + d; +>d : any + +}; +exports["a thing"] = exports; +>exports["a thing"] = exports : typeof "a thing" +>exports["a thing"] : typeof "a thing" +>exports : typeof "a thing" +>"a thing" : "a thing" +>exports : typeof "a thing" + +=== tests/cases/conformance/types/namedTypes/usage.ts === +import * as A from "./export"; +>A : typeof A + +import Result = A."a thing"; +>Result : typeof A +>A : typeof A + +export const another: Result."another one" = new Result["another one"](); +>another : A."another one" +>Result : any +>new Result["another one"]() : A."another one" +>Result["another one"] : typeof A."another one" +>Result : typeof A +>"another one" : "another one" + +export const again: A."a thing"."a thing"."another one" = null as any as A."another one"; +>again : A."another one" +>A : any +>null as any as A."another one" : A."another one" +>null as any : any +>null : null +>A : any + +export const type: typeof Result."a thing"."another one" = {} as any; +>type : typeof A."another one" +>Result."a thing"."another one" : typeof A."another one" +>Result."a thing" : typeof A +>Result : typeof A +>"a thing" : typeof A +>"another one" : typeof A."another one" +>{} as any : any +>{} : {} + +import Result2 = A.'a thing'; +>Result2 : typeof A +>A : typeof A + +export const another2: Result.'another one' = new Result['another one'](); +>another2 : A."another one" +>Result : any +>new Result['another one']() : A."another one" +>Result['another one'] : typeof A."another one" +>Result : typeof A +>'another one' : "another one" + +export const again2: A.'a thing'.'a thing'.'another one' = null as any as A.'another one'; +>again2 : A."another one" +>A : any +>null as any as A.'another one' : A."another one" +>null as any : any +>null : null +>A : any + +export const type2: typeof Result.'a thing'.'another one' = {} as any; +>type2 : typeof A."another one" +>Result.'a thing'.'another one' : typeof A."another one" +>Result.'a thing' : typeof A +>Result : typeof A +>'a thing' : typeof A +>'another one' : typeof A."another one" +>{} as any : any +>{} : {} + +import Result3 = A.`a thing`; +>Result3 : typeof A +>A : typeof A + +export const another3: Result.`another one` = new Result[`another one`](); +>another3 : A."another one" +>Result : any +>new Result[`another one`]() : A."another one" +>Result[`another one`] : typeof A."another one" +>Result : typeof A +>`another one` : "another one" + +export const again3: A.`a thing`.`a thing`.`another one` = null as any as A.`another one`; +>again3 : A."another one" +>A : any +>null as any as A.`another one` : A."another one" +>null as any : any +>null : null +>A : any + +export const type3: typeof Result.`a thing`.`another one` = {} as any; +>type3 : typeof A."another one" +>Result.`a thing`.`another one` : typeof A."another one" +>Result.`a thing` : typeof A +>Result : typeof A +>`a thing` : typeof A +>`another one` : typeof A."another one" +>{} as any : any +>{} : {} + diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt index 1ee7243beaa47..67b8067536834 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -6,9 +6,10 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(35,5) tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14): error TS2754: 'super' may not use type arguments. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34): error TS1034: 'super' must be followed by an argument list or member access. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34): error TS2339: Property '`hello world`' does not exist on type 'SomeBase'. -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (8 errors) ==== +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (9 errors) ==== export interface SomethingTaggable { (t: TemplateStringsArray, ...args: T[]): SomethingNewable; } @@ -61,6 +62,8 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34 !!! error TS2754: 'super' may not use type arguments. ~~~~~~~~~~~~~ !!! error TS1034: 'super' must be followed by an argument list or member access. + ~~~~~~~~~~~~~ +!!! error TS2339: Property '`hello world`' does not exist on type 'SomeBase'. } ~~~~~ !!! error TS2377: Constructors for derived classes must contain a 'super' call. diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js index 6ab9b7afa1d9f..5daa4902ee2b1 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -56,7 +56,7 @@ class SomeBase { } class SomeDerived extends SomeBase { constructor() { - super. `hello world`; + super.`hello world`; } } export {}; diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types index c78719846cf72..f9c6553bea054 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -92,9 +92,7 @@ class SomeDerived extends SomeBase { constructor() { super `hello world`; >super `hello world` : any ->super : any >super : SomeBase -> : any ->`hello world` : "hello world" +>`hello world` : any } } diff --git a/tests/cases/conformance/types/namedTypes/nonIdentifierNamedDirectExportsReferencable.ts b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedDirectExportsReferencable.ts new file mode 100644 index 0000000000000..a8845e477e006 --- /dev/null +++ b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedDirectExportsReferencable.ts @@ -0,0 +1,11 @@ +// @allowJs: true +// @outDir: ./out +// @filename: export.js +exports["a thing"] = class { + a; + b; +} +// @filename: usage.ts +import * as ns from "./export"; + +export const instance: ns."a thing" = new ns["a thing"](); \ No newline at end of file diff --git a/tests/cases/conformance/types/namedTypes/nonIdentifierNamedExportsReferenceable.ts b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedExportsReferenceable.ts new file mode 100644 index 0000000000000..5108bee79e117 --- /dev/null +++ b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedExportsReferenceable.ts @@ -0,0 +1,11 @@ +// @filename: a.ts +export enum Foo { + "1-1", + "1-2" +} +// @filename: b.ts +import {Foo} from "./a"; + +export type FooFirst = Foo."1-1"; + +export type FirstFoo = import("./a").Foo."1-1"; diff --git a/tests/cases/conformance/types/namedTypes/nonIdentifierNamedLocalImportAlias.ts b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedLocalImportAlias.ts new file mode 100644 index 0000000000000..de4861c4de1ad --- /dev/null +++ b/tests/cases/conformance/types/namedTypes/nonIdentifierNamedLocalImportAlias.ts @@ -0,0 +1,27 @@ +// @allowJs: true +// @outDir: ./out +// @filename: export.js +exports["another one"] = class { + c; + d; +}; +exports["a thing"] = exports; +// @filename: usage.ts +import * as A from "./export"; +import Result = A."a thing"; + +export const another: Result."another one" = new Result["another one"](); +export const again: A."a thing"."a thing"."another one" = null as any as A."another one"; +export const type: typeof Result."a thing"."another one" = {} as any; + +import Result2 = A.'a thing'; + +export const another2: Result.'another one' = new Result['another one'](); +export const again2: A.'a thing'.'a thing'.'another one' = null as any as A.'another one'; +export const type2: typeof Result.'a thing'.'another one' = {} as any; + +import Result3 = A.`a thing`; + +export const another3: Result.`another one` = new Result[`another one`](); +export const again3: A.`a thing`.`a thing`.`another one` = null as any as A.`another one`; +export const type3: typeof Result.`a thing`.`another one` = {} as any;