From 44152bc22edcf05d45faa06eae8aea2d81433ae4 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 30 Dec 2022 02:50:57 +0200 Subject: [PATCH] fix(29648): Error message related to JSDoc for non-JSDoc syntax error (#50793) * fix(29648): improve diagnostics of non-JSDoc syntax errors * fix lint errors * update tests * change diagnostic type suggestion. fix QF for jsdoc nullable type * move error handling from the parser to the checker * change diagnostic message. remove speculative parsing * update baseline --- src/compiler/checker.ts | 15 +++- src/compiler/diagnosticMessages.json | 8 ++ src/compiler/parser.ts | 1 - src/compiler/types.ts | 5 +- src/services/codefixes/fixJSDocTypes.ts | 25 +++++- .../decoratorMetadata-jsdoc.errors.txt | 8 +- ...xpressionWithJSDocTypeArguments.errors.txt | 64 +++++++-------- .../jsdocDisallowedInTypescript.errors.txt | 24 +++--- .../namedTupleMembersErrors.errors.txt | 4 +- .../parseInvalidNonNullableTypes.errors.txt | 68 ++++++++++++++++ .../reference/parseInvalidNonNullableTypes.js | 43 ++++++++++ .../parseInvalidNonNullableTypes.symbols | 51 ++++++++++++ .../parseInvalidNonNullableTypes.types | 57 +++++++++++++ .../parseInvalidNullableTypes.errors.txt | 80 +++++++++++++++++++ .../reference/parseInvalidNullableTypes.js | 47 +++++++++++ .../parseInvalidNullableTypes.symbols | 56 +++++++++++++ .../reference/parseInvalidNullableTypes.types | 63 +++++++++++++++ .../reference/restTupleElements1.errors.txt | 4 +- .../getSupportedCodeFixes-can-be-proxied.js | 6 ++ .../compiler/parseInvalidNonNullableTypes.ts | 24 ++++++ .../compiler/parseInvalidNullableTypes.ts | 26 ++++++ .../fourslash/codeFixChangeJSDocSyntax10.ts | 6 +- .../fourslash/codeFixChangeJSDocSyntax11.ts | 6 +- .../fourslash/codeFixChangeJSDocSyntax14.ts | 6 +- .../fourslash/codeFixChangeJSDocSyntax15.ts | 12 ++- .../fourslash/codeFixChangeJSDocSyntax27.ts | 11 +++ .../fourslash/codeFixChangeJSDocSyntax28.ts | 11 +++ .../fourslash/codeFixChangeJSDocSyntax5.ts | 6 +- .../fourslash/codeFixChangeJSDocSyntax6.ts | 4 +- .../fourslash/codeFixChangeJSDocSyntax_all.ts | 2 +- 30 files changed, 667 insertions(+), 76 deletions(-) create mode 100644 tests/baselines/reference/parseInvalidNonNullableTypes.errors.txt create mode 100644 tests/baselines/reference/parseInvalidNonNullableTypes.js create mode 100644 tests/baselines/reference/parseInvalidNonNullableTypes.symbols create mode 100644 tests/baselines/reference/parseInvalidNonNullableTypes.types create mode 100644 tests/baselines/reference/parseInvalidNullableTypes.errors.txt create mode 100644 tests/baselines/reference/parseInvalidNullableTypes.js create mode 100644 tests/baselines/reference/parseInvalidNullableTypes.symbols create mode 100644 tests/baselines/reference/parseInvalidNullableTypes.types create mode 100644 tests/cases/compiler/parseInvalidNonNullableTypes.ts create mode 100644 tests/cases/compiler/parseInvalidNullableTypes.ts create mode 100644 tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts create mode 100644 tests/cases/fourslash/codeFixChangeJSDocSyntax28.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e9d4e8aa44f..e66fa97327c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43294,7 +43294,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function checkJSDocTypeIsInJsFile(node: Node): void { if (!isInJSFile(node)) { - grammarErrorOnNode(node, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + if (isJSDocNonNullableType(node) || isJSDocNullableType(node)) { + const token = tokenToString(isJSDocNonNullableType(node) ? SyntaxKind.ExclamationToken : SyntaxKind.QuestionToken); + const diagnostic = node.postfix + ? Diagnostics._0_at_the_end_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1 + : Diagnostics._0_at_the_start_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1; + const typeNode = node.type; + const type = getTypeFromTypeNode(typeNode); + grammarErrorOnNode(node, diagnostic, token, typeToString( + isJSDocNullableType(node) && !(type === neverType || type === voidType) + ? getUnionType(append([type, undefinedType], node.postfix ? undefined : nullType)) : type)); + } + else { + grammarErrorOnNode(node, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); + } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 42b7b3870a7..7573cbc29ea 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6545,6 +6545,14 @@ "category": "Error", "code": 17018 }, + "'{0}' at the end of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { + "category": "Error", + "code": 17019 + }, + "'{0}' at the start of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { + "category": "Error", + "code": 17020 + }, "Circularity detected while resolving configuration: {0}": { "category": "Error", "code": 18000 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7206ef95fed..d2f481e50dd 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4809,7 +4809,6 @@ namespace Parser { if (contextFlags & NodeFlags.TypeExcludesFlags) { return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseType); } - if (isStartOfFunctionTypeOrConstructorType()) { return parseFunctionOrConstructorType(); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f3206dd4b6f..793649f9b9d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -809,12 +809,13 @@ export const enum NodeFlags { /** @internal */ PossiblyContainsDynamicImport = 1 << 21, /** @internal */ PossiblyContainsImportMeta = 1 << 22, - JSDoc = 1 << 23, // If node was parsed inside jsdoc + JSDoc = 1 << 23, // If node was parsed inside jsdoc /** @internal */ Ambient = 1 << 24, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. /** @internal */ InWithStatement = 1 << 25, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) - JsonFile = 1 << 26, // If node was parsed in a Json + JsonFile = 1 << 26, // If node was parsed in a Json /** @internal */ TypeCached = 1 << 27, // If a type was cached for node at any point /** @internal */ Deprecated = 1 << 28, // If has '@deprecated' JSDoc tag + /** @internal */ ConditionalTypeContext = 1 << 29, BlockScoped = Let | Const, diff --git a/src/services/codefixes/fixJSDocTypes.ts b/src/services/codefixes/fixJSDocTypes.ts index 0a5442600d8..3a50e757967 100644 --- a/src/services/codefixes/fixJSDocTypes.ts +++ b/src/services/codefixes/fixJSDocTypes.ts @@ -1,4 +1,5 @@ import { + append, AsExpression, CallSignatureDeclaration, CodeFixAction, @@ -10,6 +11,7 @@ import { GetAccessorDeclaration, getTokenAtPosition, IndexSignatureDeclaration, + isJSDocNullableType, MappedTypeNode, MethodDeclaration, MethodSignature, @@ -37,7 +39,12 @@ import { const fixIdPlain = "fixJSDocTypes_plain"; const fixIdNullable = "fixJSDocTypes_nullable"; -const errorCodes = [Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code]; +const errorCodes = [ + Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code, + Diagnostics._0_at_the_end_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1.code, + Diagnostics._0_at_the_start_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1.code, +]; + registerCodeFix({ errorCodes, getCodeActions(context) { @@ -51,7 +58,7 @@ registerCodeFix({ if (typeNode.kind === SyntaxKind.JSDocNullableType) { // for nullable types, suggest the flow-compatible `T | null | undefined` // in addition to the jsdoc/closure-compatible `T | null` - actions.push(fix(checker.getNullableType(type, TypeFlags.Undefined), fixIdNullable, Diagnostics.Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types)); + actions.push(fix(type, fixIdNullable, Diagnostics.Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types)); } return actions; @@ -81,7 +88,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ol function getInfo(sourceFile: SourceFile, pos: number, checker: TypeChecker): { readonly typeNode: TypeNode, readonly type: Type } | undefined { const decl = findAncestor(getTokenAtPosition(sourceFile, pos), isTypeContainer); const typeNode = decl && decl.type; - return typeNode && { typeNode, type: checker.getTypeFromTypeNode(typeNode) }; + return typeNode && { typeNode, type: getType(checker, typeNode) }; } // TODO: GH#19856 Node & { type: TypeNode } @@ -115,3 +122,15 @@ function isTypeContainer(node: Node): node is TypeContainer { return false; } } + +function getType(checker: TypeChecker, node: TypeNode) { + if (isJSDocNullableType(node)) { + const type = checker.getTypeFromTypeNode(node.type); + if (type === checker.getNeverType() || type === checker.getVoidType()) { + return type; + } + return checker.getUnionType( + append([type, checker.getUndefinedType()], node.postfix ? undefined : checker.getNullType())); + } + return checker.getTypeFromTypeNode(node); +} diff --git a/tests/baselines/reference/decoratorMetadata-jsdoc.errors.txt b/tests/baselines/reference/decoratorMetadata-jsdoc.errors.txt index a2af419361d..e2bbf1f4c67 100644 --- a/tests/baselines/reference/decoratorMetadata-jsdoc.errors.txt +++ b/tests/baselines/reference/decoratorMetadata-jsdoc.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(5,9): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(7,9): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(5,9): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(7,9): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(9,9): error TS8020: JSDoc types can only be used inside documentation comments. @@ -10,11 +10,11 @@ tests/cases/conformance/decorators/decoratorMetadata-jsdoc.ts(9,9): error TS8020 @decorator() a?: string?; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? @decorator() b?: string!; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? @decorator() c?: *; ~ diff --git a/tests/baselines/reference/expressionWithJSDocTypeArguments.errors.txt b/tests/baselines/reference/expressionWithJSDocTypeArguments.errors.txt index 6ed72dd8b3e..0063c4e8fbb 100644 --- a/tests/baselines/reference/expressionWithJSDocTypeArguments.errors.txt +++ b/tests/baselines/reference/expressionWithJSDocTypeArguments.errors.txt @@ -1,23 +1,23 @@ tests/cases/compiler/expressionWithJSDocTypeArguments.ts(9,21): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(10,20): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(11,21): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(12,23): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(12,24): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(10,20): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(11,21): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(12,23): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(12,24): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? tests/cases/compiler/expressionWithJSDocTypeArguments.ts(14,28): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(15,27): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(16,28): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(17,30): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(17,31): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(15,27): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(16,28): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(17,30): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(17,31): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? tests/cases/compiler/expressionWithJSDocTypeArguments.ts(19,21): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(20,20): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(21,21): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(22,23): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(22,24): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(20,20): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(21,21): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(22,23): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(22,24): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? tests/cases/compiler/expressionWithJSDocTypeArguments.ts(24,28): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(25,27): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(26,28): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(27,30): error TS8020: JSDoc types can only be used inside documentation comments. -tests/cases/compiler/expressionWithJSDocTypeArguments.ts(27,31): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(25,27): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(26,28): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(27,30): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/expressionWithJSDocTypeArguments.ts(27,31): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? ==== tests/cases/compiler/expressionWithJSDocTypeArguments.ts (20 errors) ==== @@ -34,58 +34,58 @@ tests/cases/compiler/expressionWithJSDocTypeArguments.ts(27,31): error TS8020: J !!! error TS8020: JSDoc types can only be used inside documentation comments. const HuhFoo = foo; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? const NopeFoo = foo; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? const ComeOnFoo = foo; ~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? type TWhatFoo = typeof foo; ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. type THuhFoo = typeof foo; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? type TNopeFoo = typeof foo; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? type TComeOnFoo = typeof foo; ~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? const WhatBar = Bar; ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. const HuhBar = Bar; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? const NopeBar = Bar; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? const ComeOnBar = Bar; ~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? type TWhatBar = typeof Bar; ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. type THuhBar = typeof Bar; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? type TNopeBar = typeof Bar; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? type TComeOnBar = typeof Bar; ~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? \ No newline at end of file diff --git a/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt index cab500645fa..83fa89bc4c9 100644 --- a/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt +++ b/tests/baselines/reference/jsdocDisallowedInTypescript.errors.txt @@ -1,5 +1,5 @@ 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,15): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? 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. @@ -7,12 +7,12 @@ tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(11,18): error TS255 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(16,11): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(17,17): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? 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(18,17): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(20,16): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? +tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(21,16): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(22,17): error TS8020: JSDoc types can only be used inside documentation comments. @@ -24,7 +24,7 @@ tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(22,17): error TS802 function f(x: ?number, y: Array.) { ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. return x ? x + y[1] : y[0]; @@ -52,22 +52,22 @@ tests/cases/conformance/jsdoc/jsdocDisallowedInTypescript.ts(22,17): error TS802 !!! 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. +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? var postfixdef: number! = 101; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? 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. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? var nns: Array; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? var dns: Array; ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? var anys: Array<*>; ~ !!! error TS8020: JSDoc types can only be used inside documentation comments. diff --git a/tests/baselines/reference/namedTupleMembersErrors.errors.txt b/tests/baselines/reference/namedTupleMembersErrors.errors.txt index 2390d50816d..fe4bb2a70b0 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.errors.txt +++ b/tests/baselines/reference/namedTupleMembersErrors.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(8,22): erro tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(10,29): error TS5086: A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(12,46): error TS5087: A labeled tuple element is declared as rest with a '...' before the name, rather than before the type. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(14,49): error TS5087: A labeled tuple element is declared as rest with a '...' before the name, rather than before the type. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(14,52): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(14,52): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string[]'? tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(16,39): error TS5085: A tuple member cannot be both optional and rest. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,44): error TS2574: A rest element type must be an array type. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(20,13): error TS2456: Type alias 'RecusiveRestUnlabeled' circularly references itself. @@ -48,7 +48,7 @@ tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(21,13): err ~~~~~~~~~~~~ !!! error TS5087: A labeled tuple element is declared as rest with a '...' before the name, rather than before the type. ~~~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string[]'? export type OptRest = [first: string, ...rest?: string[]]; // rest+optional disallowed ~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/parseInvalidNonNullableTypes.errors.txt b/tests/baselines/reference/parseInvalidNonNullableTypes.errors.txt new file mode 100644 index 00000000000..a5b8dbef915 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNonNullableTypes.errors.txt @@ -0,0 +1,68 @@ +tests/cases/compiler/parseInvalidNonNullableTypes.ts(1,30): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(5,30): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(9,16): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(10,16): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(12,16): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(13,16): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(15,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. +tests/cases/compiler/parseInvalidNonNullableTypes.ts(15,16): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(16,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. +tests/cases/compiler/parseInvalidNonNullableTypes.ts(16,16): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(18,16): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'any'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(19,10): error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(21,16): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'any'? +tests/cases/compiler/parseInvalidNonNullableTypes.ts(22,10): error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? + + +==== tests/cases/compiler/parseInvalidNonNullableTypes.ts (14 errors) ==== + function f1(a: string): a is string! { + ~~~~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? + return true; + } + + function f2(a: string): a is !string { + ~~~~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? + return true; + } + + function f3(a: string!) {} + ~~~~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? + function f4(a: number!) {} + ~~~~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? + + function f5(a: !string) {} + ~~~~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? + function f6(a: !number) {} + ~~~~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? + + function f7(): string! {} + ~~~~~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. + ~~~~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string'? + function f8(): !string {} + ~~~~~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. + ~~~~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string'? + + const a = 1 as any!; + ~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'any'? + const b: number! = 1; + ~~~~~~~ +!!! error TS17019: '!' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number'? + + const c = 1 as !any; + ~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'any'? + const d: !number = 1; + ~~~~~~~ +!!! error TS17020: '!' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number'? + \ No newline at end of file diff --git a/tests/baselines/reference/parseInvalidNonNullableTypes.js b/tests/baselines/reference/parseInvalidNonNullableTypes.js new file mode 100644 index 00000000000..c73228ab0d3 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNonNullableTypes.js @@ -0,0 +1,43 @@ +//// [parseInvalidNonNullableTypes.ts] +function f1(a: string): a is string! { + return true; +} + +function f2(a: string): a is !string { + return true; +} + +function f3(a: string!) {} +function f4(a: number!) {} + +function f5(a: !string) {} +function f6(a: !number) {} + +function f7(): string! {} +function f8(): !string {} + +const a = 1 as any!; +const b: number! = 1; + +const c = 1 as !any; +const d: !number = 1; + + +//// [parseInvalidNonNullableTypes.js] +"use strict"; +function f1(a) { + return true; +} +function f2(a) { + return true; +} +function f3(a) { } +function f4(a) { } +function f5(a) { } +function f6(a) { } +function f7() { } +function f8() { } +var a = 1; +var b = 1; +var c = 1; +var d = 1; diff --git a/tests/baselines/reference/parseInvalidNonNullableTypes.symbols b/tests/baselines/reference/parseInvalidNonNullableTypes.symbols new file mode 100644 index 00000000000..38f7db44552 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNonNullableTypes.symbols @@ -0,0 +1,51 @@ +=== tests/cases/compiler/parseInvalidNonNullableTypes.ts === +function f1(a: string): a is string! { +>f1 : Symbol(f1, Decl(parseInvalidNonNullableTypes.ts, 0, 0)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 0, 12)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 0, 12)) + + return true; +} + +function f2(a: string): a is !string { +>f2 : Symbol(f2, Decl(parseInvalidNonNullableTypes.ts, 2, 1)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 4, 12)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 4, 12)) + + return true; +} + +function f3(a: string!) {} +>f3 : Symbol(f3, Decl(parseInvalidNonNullableTypes.ts, 6, 1)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 8, 12)) + +function f4(a: number!) {} +>f4 : Symbol(f4, Decl(parseInvalidNonNullableTypes.ts, 8, 26)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 9, 12)) + +function f5(a: !string) {} +>f5 : Symbol(f5, Decl(parseInvalidNonNullableTypes.ts, 9, 26)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 11, 12)) + +function f6(a: !number) {} +>f6 : Symbol(f6, Decl(parseInvalidNonNullableTypes.ts, 11, 26)) +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 12, 12)) + +function f7(): string! {} +>f7 : Symbol(f7, Decl(parseInvalidNonNullableTypes.ts, 12, 26)) + +function f8(): !string {} +>f8 : Symbol(f8, Decl(parseInvalidNonNullableTypes.ts, 14, 25)) + +const a = 1 as any!; +>a : Symbol(a, Decl(parseInvalidNonNullableTypes.ts, 17, 5)) + +const b: number! = 1; +>b : Symbol(b, Decl(parseInvalidNonNullableTypes.ts, 18, 5)) + +const c = 1 as !any; +>c : Symbol(c, Decl(parseInvalidNonNullableTypes.ts, 20, 5)) + +const d: !number = 1; +>d : Symbol(d, Decl(parseInvalidNonNullableTypes.ts, 21, 5)) + diff --git a/tests/baselines/reference/parseInvalidNonNullableTypes.types b/tests/baselines/reference/parseInvalidNonNullableTypes.types new file mode 100644 index 00000000000..9bb7a95163b --- /dev/null +++ b/tests/baselines/reference/parseInvalidNonNullableTypes.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/parseInvalidNonNullableTypes.ts === +function f1(a: string): a is string! { +>f1 : (a: string) => a is string +>a : string + + return true; +>true : true +} + +function f2(a: string): a is !string { +>f2 : (a: string) => a is string +>a : string + + return true; +>true : true +} + +function f3(a: string!) {} +>f3 : (a: string) => void +>a : string + +function f4(a: number!) {} +>f4 : (a: number) => void +>a : number + +function f5(a: !string) {} +>f5 : (a: string) => void +>a : string + +function f6(a: !number) {} +>f6 : (a: number) => void +>a : number + +function f7(): string! {} +>f7 : () => string + +function f8(): !string {} +>f8 : () => string + +const a = 1 as any!; +>a : any +>1 as any! : any +>1 : 1 + +const b: number! = 1; +>b : number +>1 : 1 + +const c = 1 as !any; +>c : any +>1 as !any : any +>1 : 1 + +const d: !number = 1; +>d : number +>1 : 1 + diff --git a/tests/baselines/reference/parseInvalidNullableTypes.errors.txt b/tests/baselines/reference/parseInvalidNullableTypes.errors.txt new file mode 100644 index 00000000000..0a40d386044 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNullableTypes.errors.txt @@ -0,0 +1,80 @@ +tests/cases/compiler/parseInvalidNullableTypes.ts(1,30): error TS2677: A type predicate's type must be assignable to its parameter's type. + Type 'string | null' is not assignable to type 'string'. + Type 'null' is not assignable to type 'string'. +tests/cases/compiler/parseInvalidNullableTypes.ts(1,30): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(5,16): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(6,16): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(8,16): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(9,16): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(11,25): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(12,5): error TS2322: Type 'boolean' is not assignable to type 'string'. +tests/cases/compiler/parseInvalidNullableTypes.ts(15,16): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'any'? +tests/cases/compiler/parseInvalidNullableTypes.ts(16,10): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(18,16): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'any'? +tests/cases/compiler/parseInvalidNullableTypes.ts(19,10): error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? +tests/cases/compiler/parseInvalidNullableTypes.ts(21,8): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'unknown'? +tests/cases/compiler/parseInvalidNullableTypes.ts(22,8): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'never'? +tests/cases/compiler/parseInvalidNullableTypes.ts(23,8): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'void'? +tests/cases/compiler/parseInvalidNullableTypes.ts(24,8): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'undefined'? + + +==== tests/cases/compiler/parseInvalidNullableTypes.ts (16 errors) ==== + function f1(a: string): a is ?string { + ~~~~~~~ +!!! error TS2677: A type predicate's type must be assignable to its parameter's type. +!!! error TS2677: Type 'string | null' is not assignable to type 'string'. +!!! error TS2677: Type 'null' is not assignable to type 'string'. + ~~~~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? + return true; + } + + function f2(a: string?) {} + ~~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? + function f3(a: number?) {} + ~~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? + + function f4(a: ?string) {} + ~~~~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? + function f5(a: ?number) {} + ~~~~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? + + function f6(a: string): ?string { + ~~~~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'string | null | undefined'? + return true; + ~~~~~~~~~~~~ +!!! error TS2322: Type 'boolean' is not assignable to type 'string'. + } + + const a = 1 as any?; + ~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'any'? + const b: number? = 1; + ~~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'number | undefined'? + + const c = 1 as ?any; + ~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'any'? + const d: ?number = 1; + ~~~~~~~ +!!! error TS17020: '?' at the start of a type is not valid TypeScript syntax. Did you mean to write 'number | null | undefined'? + + let e: unknown?; + ~~~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'unknown'? + let f: never?; + ~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'never'? + let g: void?; + ~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'void'? + let h: undefined?; + ~~~~~~~~~~ +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'undefined'? + \ No newline at end of file diff --git a/tests/baselines/reference/parseInvalidNullableTypes.js b/tests/baselines/reference/parseInvalidNullableTypes.js new file mode 100644 index 00000000000..12f00fb9792 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNullableTypes.js @@ -0,0 +1,47 @@ +//// [parseInvalidNullableTypes.ts] +function f1(a: string): a is ?string { + return true; +} + +function f2(a: string?) {} +function f3(a: number?) {} + +function f4(a: ?string) {} +function f5(a: ?number) {} + +function f6(a: string): ?string { + return true; +} + +const a = 1 as any?; +const b: number? = 1; + +const c = 1 as ?any; +const d: ?number = 1; + +let e: unknown?; +let f: never?; +let g: void?; +let h: undefined?; + + +//// [parseInvalidNullableTypes.js] +"use strict"; +function f1(a) { + return true; +} +function f2(a) { } +function f3(a) { } +function f4(a) { } +function f5(a) { } +function f6(a) { + return true; +} +var a = 1; +var b = 1; +var c = 1; +var d = 1; +var e; +var f; +var g; +var h; diff --git a/tests/baselines/reference/parseInvalidNullableTypes.symbols b/tests/baselines/reference/parseInvalidNullableTypes.symbols new file mode 100644 index 00000000000..2e21df14274 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNullableTypes.symbols @@ -0,0 +1,56 @@ +=== tests/cases/compiler/parseInvalidNullableTypes.ts === +function f1(a: string): a is ?string { +>f1 : Symbol(f1, Decl(parseInvalidNullableTypes.ts, 0, 0)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 0, 12)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 0, 12)) + + return true; +} + +function f2(a: string?) {} +>f2 : Symbol(f2, Decl(parseInvalidNullableTypes.ts, 2, 1)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 4, 12)) + +function f3(a: number?) {} +>f3 : Symbol(f3, Decl(parseInvalidNullableTypes.ts, 4, 26)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 5, 12)) + +function f4(a: ?string) {} +>f4 : Symbol(f4, Decl(parseInvalidNullableTypes.ts, 5, 26)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 7, 12)) + +function f5(a: ?number) {} +>f5 : Symbol(f5, Decl(parseInvalidNullableTypes.ts, 7, 26)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 8, 12)) + +function f6(a: string): ?string { +>f6 : Symbol(f6, Decl(parseInvalidNullableTypes.ts, 8, 26)) +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 10, 12)) + + return true; +} + +const a = 1 as any?; +>a : Symbol(a, Decl(parseInvalidNullableTypes.ts, 14, 5)) + +const b: number? = 1; +>b : Symbol(b, Decl(parseInvalidNullableTypes.ts, 15, 5)) + +const c = 1 as ?any; +>c : Symbol(c, Decl(parseInvalidNullableTypes.ts, 17, 5)) + +const d: ?number = 1; +>d : Symbol(d, Decl(parseInvalidNullableTypes.ts, 18, 5)) + +let e: unknown?; +>e : Symbol(e, Decl(parseInvalidNullableTypes.ts, 20, 3)) + +let f: never?; +>f : Symbol(f, Decl(parseInvalidNullableTypes.ts, 21, 3)) + +let g: void?; +>g : Symbol(g, Decl(parseInvalidNullableTypes.ts, 22, 3)) + +let h: undefined?; +>h : Symbol(h, Decl(parseInvalidNullableTypes.ts, 23, 3)) + diff --git a/tests/baselines/reference/parseInvalidNullableTypes.types b/tests/baselines/reference/parseInvalidNullableTypes.types new file mode 100644 index 00000000000..8612870b672 --- /dev/null +++ b/tests/baselines/reference/parseInvalidNullableTypes.types @@ -0,0 +1,63 @@ +=== tests/cases/compiler/parseInvalidNullableTypes.ts === +function f1(a: string): a is ?string { +>f1 : (a: string) => a is string | null +>a : string + + return true; +>true : true +} + +function f2(a: string?) {} +>f2 : (a: string | null) => void +>a : string | null + +function f3(a: number?) {} +>f3 : (a: number | null) => void +>a : number | null + +function f4(a: ?string) {} +>f4 : (a: string | null) => void +>a : string | null + +function f5(a: ?number) {} +>f5 : (a: number | null) => void +>a : number | null + +function f6(a: string): ?string { +>f6 : (a: string) => string | null +>a : string + + return true; +>true : true +} + +const a = 1 as any?; +>a : any +>1 as any? : any +>1 : 1 + +const b: number? = 1; +>b : number | null +>1 : 1 + +const c = 1 as ?any; +>c : any +>1 as ?any : any +>1 : 1 + +const d: ?number = 1; +>d : number | null +>1 : 1 + +let e: unknown?; +>e : unknown + +let f: never?; +>f : null + +let g: void?; +>g : void | null + +let h: undefined?; +>h : null | undefined + diff --git a/tests/baselines/reference/restTupleElements1.errors.txt b/tests/baselines/reference/restTupleElements1.errors.txt index 896639cb8e6..8d297b1f06b 100644 --- a/tests/baselines/reference/restTupleElements1.errors.txt +++ b/tests/baselines/reference/restTupleElements1.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(3,22): error TS1257: A required element cannot follow an optional element. tests/cases/conformance/types/tuple/restTupleElements1.ts(9,13): error TS2574: A rest element type must be an array type. tests/cases/conformance/types/tuple/restTupleElements1.ts(10,13): error TS2574: A rest element type must be an array type. -tests/cases/conformance/types/tuple/restTupleElements1.ts(10,16): error TS8020: JSDoc types can only be used inside documentation comments. +tests/cases/conformance/types/tuple/restTupleElements1.ts(10,16): error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? tests/cases/conformance/types/tuple/restTupleElements1.ts(23,31): error TS2344: Type 'number[]' does not satisfy the constraint '[number, ...number[]]'. Source provides no match for required element at position 0 in target. tests/cases/conformance/types/tuple/restTupleElements1.ts(24,31): error TS2344: Type '[]' does not satisfy the constraint '[number, ...number[]]'. @@ -44,7 +44,7 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A ~~~~~~~~~~ !!! error TS2574: A rest element type must be an array type. ~~~~~~~ -!!! error TS8020: JSDoc types can only be used inside documentation comments. +!!! error TS17019: '?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'? type T10 = [string, ...[...string[]]]; type T11 = [string, ...[...[...string[]]]]; diff --git a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js index ca042c97622..a5315f584b3 100644 --- a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js +++ b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js @@ -378,6 +378,8 @@ Info 32 [00:01:13.000] response: "7027", "7028", "8020", + "17019", + "17020", "2774", "1308", "1103", @@ -1708,6 +1710,8 @@ Info 38 [00:01:19.000] response: "7027", "7028", "8020", + "17019", + "17020", "2774", "1308", "1103", @@ -2950,6 +2954,8 @@ Info 40 [00:01:21.000] response: "7027", "7028", "8020", + "17019", + "17020", "2774", "1308", "1103", diff --git a/tests/cases/compiler/parseInvalidNonNullableTypes.ts b/tests/cases/compiler/parseInvalidNonNullableTypes.ts new file mode 100644 index 00000000000..f1ad19c6a2d --- /dev/null +++ b/tests/cases/compiler/parseInvalidNonNullableTypes.ts @@ -0,0 +1,24 @@ +// @strict: true + +function f1(a: string): a is string! { + return true; +} + +function f2(a: string): a is !string { + return true; +} + +function f3(a: string!) {} +function f4(a: number!) {} + +function f5(a: !string) {} +function f6(a: !number) {} + +function f7(): string! {} +function f8(): !string {} + +const a = 1 as any!; +const b: number! = 1; + +const c = 1 as !any; +const d: !number = 1; diff --git a/tests/cases/compiler/parseInvalidNullableTypes.ts b/tests/cases/compiler/parseInvalidNullableTypes.ts new file mode 100644 index 00000000000..f7d9f264351 --- /dev/null +++ b/tests/cases/compiler/parseInvalidNullableTypes.ts @@ -0,0 +1,26 @@ +// @strict: true + +function f1(a: string): a is ?string { + return true; +} + +function f2(a: string?) {} +function f3(a: number?) {} + +function f4(a: ?string) {} +function f5(a: ?number) {} + +function f6(a: string): ?string { + return true; +} + +const a = 1 as any?; +const b: number? = 1; + +const c = 1 as ?any; +const d: ?number = 1; + +let e: unknown?; +let f: never?; +let g: void?; +let h: undefined?; diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts index 755454a591f..404ce293c47 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts @@ -4,8 +4,8 @@ //// } verify.codeFix({ - description: "Change 'number?' to 'number | null'", - errorCode: 8020, + description: "Change 'number?' to 'number | undefined'", + errorCode: 17019, index: 0, - newRangeContent: "number | null", + newRangeContent: "number | undefined", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts index 4b606e0d209..ac483849943 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts @@ -4,8 +4,8 @@ //// } verify.codeFix({ - description: "Change 'string?' to 'string | null | undefined'", - errorCode: 8020, + description: "Change 'string?' to 'string | undefined'", + errorCode: 17019, index: 1, - newRangeContent: "string | null | undefined", + newRangeContent: "string | undefined", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts index e0eb15dac95..970f55cc154 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts @@ -3,8 +3,8 @@ //// var x = 12 as [|number?|]; verify.codeFix({ - description: "Change 'number?' to 'number | null'", - errorCode: 8020, + description: "Change 'number?' to 'number | undefined'", + errorCode: 17019, index: 0, - newRangeContent: "number | null", + newRangeContent: "number | undefined", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts index 62c621b84d8..748eae27161 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts @@ -2,8 +2,16 @@ //// var f = <[|function(number?): number|]>(x => x); verify.codeFix({ - description: "Change 'function(number?): number' to '(arg0: number) => number'", + description: "Change 'number?' to 'number'", + errorCode: 17019, + index: 0, + newRangeContent: "function(number): number", + applyChanges: true +}); + +verify.codeFix({ + description: "Change 'function(number): number' to '(arg0: number) => number'", errorCode: 8020, index: 0, - newRangeContent: "(arg0: number | null) => number", + newRangeContent: "(arg0: number) => number", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts new file mode 100644 index 00000000000..32d0b953e4a --- /dev/null +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts @@ -0,0 +1,11 @@ +// @strict: true +/// +//// function f(x: [|never?|]) { +//// } + +verify.codeFix({ + description: "Change 'never?' to 'never'", + errorCode: 17019, + index: 0, + newRangeContent: "never", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax28.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax28.ts new file mode 100644 index 00000000000..f9681bea54d --- /dev/null +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax28.ts @@ -0,0 +1,11 @@ +// @strict: true +/// +//// function f(x: [|void?|]) { +//// } + +verify.codeFix({ + description: "Change 'void?' to 'void'", + errorCode: 17019, + index: 0, + newRangeContent: "void", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts index c29a9b6a942..bd86022d8f5 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts @@ -3,8 +3,8 @@ //// var x: [|?number|] = 12; verify.codeFix({ - description: "Change '?number' to 'number | null'", - errorCode: 8020, + description: "Change '?number' to 'number | null | undefined'", + errorCode: 17020, index: 0, - newRangeContent: "number | null", + newRangeContent: "number | null | undefined", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts index 29aa512751f..470042f664e 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts @@ -3,7 +3,7 @@ //// var x: [|number?|] = 12; verify.codeFix({ - description: "Change 'number?' to 'number | null | undefined'", + description: "Change 'number?' to 'number | undefined'", index: 1, - newRangeContent: "number | null | undefined", + newRangeContent: "number | undefined", }); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax_all.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax_all.ts index 03a51a02f4e..c2372689aad 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax_all.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax_all.ts @@ -6,5 +6,5 @@ verify.codeFixAll({ fixId: "fixJSDocTypes_plain", fixAllDescription: "Change all jsdoc-style types to TypeScript", - newFileContent: "function f(a: number | null, b: string) {}", + newFileContent: "function f(a: number | null | undefined, b: string) {}", })