diff --git a/.github/tsc.json b/.github/tsc.json new file mode 100644 index 0000000000000..158f7e83d3a1b --- /dev/null +++ b/.github/tsc.json @@ -0,0 +1,18 @@ +{ + "problemMatcher": [ + { + "owner": "tsc", + "pattern": [ + { + "regexp": "^(?:\\s+\\d+\\>)?([^\\s].*)\\((\\d+),(\\d+)\\)\\s*:\\s+(error|warning|info)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6 + } + ] + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 251303b0c952b..32e5fa02b36c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: node-version: [10.x, 12.x, 13.x] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: fetch-depth: 5 - name: Use node version ${{ matrix.node-version }} @@ -30,12 +30,19 @@ jobs: run: | npm uninstall typescript --no-save npm uninstall tslint --no-save - - name: npm install and test - run: | - npm install - npm update - npm test - + - run: npm install + - run: npm update + + # Re: https://github.com/actions/setup-node/pull/125 + - name: Register Problem Matcher for TSC + run: echo "##[add-matcher].github/tsc.json" + + - name: Tests + run: npm test -- --no-lint + + - name: Linter + run: npm run lint:ci + - name: Validate the browser can import TypeScript run: gulp test-browser-integration - \ No newline at end of file + diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 99a8a007ac36d..24c3ed774f339 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -3,6 +3,8 @@ name: Publish Nightly on: schedule: - cron: '0 7 * * *' + # enable users to manually trigger with workflow_dispatch + workflow_dispatch: {} repository_dispatch: types: publish-nightly diff --git a/.github/workflows/twoslash-repros.yaml b/.github/workflows/twoslash-repros.yaml new file mode 100644 index 0000000000000..f4888f5334163 --- /dev/null +++ b/.github/workflows/twoslash-repros.yaml @@ -0,0 +1,23 @@ +name: Twoslash Code Sample Repros + +on: + push: + branches: + - orta-twoslash-repros + schedule: + - cron: '0 8 * * *' + repository_dispatch: + types: run-twoslash-repros + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Use node + uses: actions/setup-node@v1 + - run: | + npm init -y + npm install --save typescript@next + - uses: microsoft/TypeScript-Twoslash-Repro-Action@master + with: + github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 756b2a12028f4..9c7f69b24e2c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,7 +63,7 @@ TypeScript is currently accepting contributions in the form of bug fixes. A bug ## Contributing features -Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved (labelled ["help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or in the "Backlog" milestone) by a TypeScript project maintainer) in the suggestion issue. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted. +Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved (labelled ["help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or in the "Backlog" milestone) by a TypeScript project maintainer in the suggestion issue. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted. Design changes will not be accepted at this time. If you have a design change proposal, please log a suggestion issue. diff --git a/Gulpfile.js b/Gulpfile.js index 095ea5025c4d0..7bd32515ba5fe 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -350,11 +350,12 @@ const lintFoldEnd = async () => { if (fold.isTravis()) console.log(fold.end("lin /** @type { (folder: string) => { (): Promise; displayName?: string } } */ const eslint = (folder) => async () => { + const formatter = cmdLineOptions.ci ? "stylish" : "autolinkable-stylish"; const args = [ "node_modules/eslint/bin/eslint", "--cache", "--cache-location", `${folder}/.eslintcache`, - "--format", "autolinkable-stylish", + "--format", formatter, "--rulesdir", "scripts/eslint/built/rules", "--ext", ".ts", ]; @@ -367,7 +368,7 @@ const eslint = (folder) => async () => { log(`Linting: ${args.join(" ")}`); return exec(process.execPath, args); -} +}; const lintScripts = eslint("scripts"); lintScripts.displayName = "lint-scripts"; diff --git a/lib/diagnosticMessages.generated.json b/lib/diagnosticMessages.generated.json deleted file mode 100644 index 7bb74d31a4ee2..0000000000000 --- a/lib/diagnosticMessages.generated.json +++ /dev/null @@ -1,1047 +0,0 @@ -{ - "Unterminated_string_literal_1002" : "Unterminated string literal.", - "Identifier_expected_1003" : "Identifier expected.", - "_0_expected_1005" : "'{0}' expected.", - "A_file_cannot_have_a_reference_to_itself_1006" : "A file cannot have a reference to itself.", - "Trailing_comma_not_allowed_1009" : "Trailing comma not allowed.", - "Asterisk_Slash_expected_1010" : "'*/' expected.", - "An_element_access_expression_should_take_an_argument_1011" : "An element access expression should take an argument.", - "Unexpected_token_1012" : "Unexpected token.", - "A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013" : "A rest parameter or binding pattern may not have a trailing comma.", - "A_rest_parameter_must_be_last_in_a_parameter_list_1014" : "A rest parameter must be last in a parameter list.", - "Parameter_cannot_have_question_mark_and_initializer_1015" : "Parameter cannot have question mark and initializer.", - "A_required_parameter_cannot_follow_an_optional_parameter_1016" : "A required parameter cannot follow an optional parameter.", - "An_index_signature_cannot_have_a_rest_parameter_1017" : "An index signature cannot have a rest parameter.", - "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018" : "An index signature parameter cannot have an accessibility modifier.", - "An_index_signature_parameter_cannot_have_a_question_mark_1019" : "An index signature parameter cannot have a question mark.", - "An_index_signature_parameter_cannot_have_an_initializer_1020" : "An index signature parameter cannot have an initializer.", - "An_index_signature_must_have_a_type_annotation_1021" : "An index signature must have a type annotation.", - "An_index_signature_parameter_must_have_a_type_annotation_1022" : "An index signature parameter must have a type annotation.", - "An_index_signature_parameter_type_must_be_string_or_number_1023" : "An index signature parameter type must be 'string' or 'number'.", - "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024" : "'readonly' modifier can only appear on a property declaration or index signature.", - "Accessibility_modifier_already_seen_1028" : "Accessibility modifier already seen.", - "_0_modifier_must_precede_1_modifier_1029" : "'{0}' modifier must precede '{1}' modifier.", - "_0_modifier_already_seen_1030" : "'{0}' modifier already seen.", - "_0_modifier_cannot_appear_on_a_class_element_1031" : "'{0}' modifier cannot appear on a class element.", - "super_must_be_followed_by_an_argument_list_or_member_access_1034" : "'super' must be followed by an argument list or member access.", - "Only_ambient_modules_can_use_quoted_names_1035" : "Only ambient modules can use quoted names.", - "Statements_are_not_allowed_in_ambient_contexts_1036" : "Statements are not allowed in ambient contexts.", - "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038" : "A 'declare' modifier cannot be used in an already ambient context.", - "Initializers_are_not_allowed_in_ambient_contexts_1039" : "Initializers are not allowed in ambient contexts.", - "_0_modifier_cannot_be_used_in_an_ambient_context_1040" : "'{0}' modifier cannot be used in an ambient context.", - "_0_modifier_cannot_be_used_with_a_class_declaration_1041" : "'{0}' modifier cannot be used with a class declaration.", - "_0_modifier_cannot_be_used_here_1042" : "'{0}' modifier cannot be used here.", - "_0_modifier_cannot_appear_on_a_data_property_1043" : "'{0}' modifier cannot appear on a data property.", - "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044" : "'{0}' modifier cannot appear on a module or namespace element.", - "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045" : "A '{0}' modifier cannot be used with an interface declaration.", - "A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046" : "A 'declare' modifier is required for a top level declaration in a .d.ts file.", - "A_rest_parameter_cannot_be_optional_1047" : "A rest parameter cannot be optional.", - "A_rest_parameter_cannot_have_an_initializer_1048" : "A rest parameter cannot have an initializer.", - "A_set_accessor_must_have_exactly_one_parameter_1049" : "A 'set' accessor must have exactly one parameter.", - "A_set_accessor_cannot_have_an_optional_parameter_1051" : "A 'set' accessor cannot have an optional parameter.", - "A_set_accessor_parameter_cannot_have_an_initializer_1052" : "A 'set' accessor parameter cannot have an initializer.", - "A_set_accessor_cannot_have_rest_parameter_1053" : "A 'set' accessor cannot have rest parameter.", - "A_get_accessor_cannot_have_parameters_1054" : "A 'get' accessor cannot have parameters.", - "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055" : "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.", - "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056" : "Accessors are only available when targeting ECMAScript 5 and higher.", - "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057" : "An async function or method must have a valid awaitable return type.", - "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058" : "The return type of an async function must either be a valid promise or must not contain a callable 'then' member.", - "A_promise_must_have_a_then_method_1059" : "A promise must have a 'then' method.", - "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060" : "The first parameter of the 'then' method of a promise must be a callback.", - "Enum_member_must_have_initializer_1061" : "Enum member must have initializer.", - "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062" : "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.", - "An_export_assignment_cannot_be_used_in_a_namespace_1063" : "An export assignment cannot be used in a namespace.", - "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064" : "The return type of an async function or method must be the global Promise type.", - "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066" : "In ambient enum declarations member initializer must be constant expression.", - "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068" : "Unexpected token. A constructor, method, accessor, or property was expected.", - "_0_modifier_cannot_appear_on_a_type_member_1070" : "'{0}' modifier cannot appear on a type member.", - "_0_modifier_cannot_appear_on_an_index_signature_1071" : "'{0}' modifier cannot appear on an index signature.", - "A_0_modifier_cannot_be_used_with_an_import_declaration_1079" : "A '{0}' modifier cannot be used with an import declaration.", - "Invalid_reference_directive_syntax_1084" : "Invalid 'reference' directive syntax.", - "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085" : "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'.", - "An_accessor_cannot_be_declared_in_an_ambient_context_1086" : "An accessor cannot be declared in an ambient context.", - "_0_modifier_cannot_appear_on_a_constructor_declaration_1089" : "'{0}' modifier cannot appear on a constructor declaration.", - "_0_modifier_cannot_appear_on_a_parameter_1090" : "'{0}' modifier cannot appear on a parameter.", - "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091" : "Only a single variable declaration is allowed in a 'for...in' statement.", - "Type_parameters_cannot_appear_on_a_constructor_declaration_1092" : "Type parameters cannot appear on a constructor declaration.", - "Type_annotation_cannot_appear_on_a_constructor_declaration_1093" : "Type annotation cannot appear on a constructor declaration.", - "An_accessor_cannot_have_type_parameters_1094" : "An accessor cannot have type parameters.", - "A_set_accessor_cannot_have_a_return_type_annotation_1095" : "A 'set' accessor cannot have a return type annotation.", - "An_index_signature_must_have_exactly_one_parameter_1096" : "An index signature must have exactly one parameter.", - "_0_list_cannot_be_empty_1097" : "'{0}' list cannot be empty.", - "Type_parameter_list_cannot_be_empty_1098" : "Type parameter list cannot be empty.", - "Type_argument_list_cannot_be_empty_1099" : "Type argument list cannot be empty.", - "Invalid_use_of_0_in_strict_mode_1100" : "Invalid use of '{0}' in strict mode.", - "with_statements_are_not_allowed_in_strict_mode_1101" : "'with' statements are not allowed in strict mode.", - "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102" : "'delete' cannot be called on an identifier in strict mode.", - "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103" : "A 'for-await-of' statement is only allowed within an async function or async generator.", - "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104" : "A 'continue' statement can only be used within an enclosing iteration statement.", - "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105" : "A 'break' statement can only be used within an enclosing iteration or switch statement.", - "Jump_target_cannot_cross_function_boundary_1107" : "Jump target cannot cross function boundary.", - "A_return_statement_can_only_be_used_within_a_function_body_1108" : "A 'return' statement can only be used within a function body.", - "Expression_expected_1109" : "Expression expected.", - "Type_expected_1110" : "Type expected.", - "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113" : "A 'default' clause cannot appear more than once in a 'switch' statement.", - "Duplicate_label_0_1114" : "Duplicate label '{0}'.", - "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115" : "A 'continue' statement can only jump to a label of an enclosing iteration statement.", - "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116" : "A 'break' statement can only jump to a label of an enclosing statement.", - "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117" : "An object literal cannot have multiple properties with the same name in strict mode.", - "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118" : "An object literal cannot have multiple get/set accessors with the same name.", - "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119" : "An object literal cannot have property and accessor with the same name.", - "An_export_assignment_cannot_have_modifiers_1120" : "An export assignment cannot have modifiers.", - "Octal_literals_are_not_allowed_in_strict_mode_1121" : "Octal literals are not allowed in strict mode.", - "A_tuple_type_element_list_cannot_be_empty_1122" : "A tuple type element list cannot be empty.", - "Variable_declaration_list_cannot_be_empty_1123" : "Variable declaration list cannot be empty.", - "Digit_expected_1124" : "Digit expected.", - "Hexadecimal_digit_expected_1125" : "Hexadecimal digit expected.", - "Unexpected_end_of_text_1126" : "Unexpected end of text.", - "Invalid_character_1127" : "Invalid character.", - "Declaration_or_statement_expected_1128" : "Declaration or statement expected.", - "Statement_expected_1129" : "Statement expected.", - "case_or_default_expected_1130" : "'case' or 'default' expected.", - "Property_or_signature_expected_1131" : "Property or signature expected.", - "Enum_member_expected_1132" : "Enum member expected.", - "Variable_declaration_expected_1134" : "Variable declaration expected.", - "Argument_expression_expected_1135" : "Argument expression expected.", - "Property_assignment_expected_1136" : "Property assignment expected.", - "Expression_or_comma_expected_1137" : "Expression or comma expected.", - "Parameter_declaration_expected_1138" : "Parameter declaration expected.", - "Type_parameter_declaration_expected_1139" : "Type parameter declaration expected.", - "Type_argument_expected_1140" : "Type argument expected.", - "String_literal_expected_1141" : "String literal expected.", - "Line_break_not_permitted_here_1142" : "Line break not permitted here.", - "or_expected_1144" : "'{' or ';' expected.", - "Declaration_expected_1146" : "Declaration expected.", - "Import_declarations_in_a_namespace_cannot_reference_a_module_1147" : "Import declarations in a namespace cannot reference a module.", - "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148" : "Cannot use imports, exports, or module augmentations when '--module' is 'none'.", - "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149" : "File name '{0}' differs from already included file name '{1}' only in casing.", - "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150" : "'new T[]' cannot be used to create an array. Use 'new Array()' instead.", - "const_declarations_must_be_initialized_1155" : "'const' declarations must be initialized.", - "const_declarations_can_only_be_declared_inside_a_block_1156" : "'const' declarations can only be declared inside a block.", - "let_declarations_can_only_be_declared_inside_a_block_1157" : "'let' declarations can only be declared inside a block.", - "Unterminated_template_literal_1160" : "Unterminated template literal.", - "Unterminated_regular_expression_literal_1161" : "Unterminated regular expression literal.", - "An_object_member_cannot_be_declared_optional_1162" : "An object member cannot be declared optional.", - "A_yield_expression_is_only_allowed_in_a_generator_body_1163" : "A 'yield' expression is only allowed in a generator body.", - "Computed_property_names_are_not_allowed_in_enums_1164" : "Computed property names are not allowed in enums.", - "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165" : "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type.", - "A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166" : "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.", - "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168" : "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.", - "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169" : "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.", - "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170" : "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.", - "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171" : "A comma expression is not allowed in a computed property name.", - "extends_clause_already_seen_1172" : "'extends' clause already seen.", - "extends_clause_must_precede_implements_clause_1173" : "'extends' clause must precede 'implements' clause.", - "Classes_can_only_extend_a_single_class_1174" : "Classes can only extend a single class.", - "implements_clause_already_seen_1175" : "'implements' clause already seen.", - "Interface_declaration_cannot_have_implements_clause_1176" : "Interface declaration cannot have 'implements' clause.", - "Binary_digit_expected_1177" : "Binary digit expected.", - "Octal_digit_expected_1178" : "Octal digit expected.", - "Unexpected_token_expected_1179" : "Unexpected token. '{' expected.", - "Property_destructuring_pattern_expected_1180" : "Property destructuring pattern expected.", - "Array_element_destructuring_pattern_expected_1181" : "Array element destructuring pattern expected.", - "A_destructuring_declaration_must_have_an_initializer_1182" : "A destructuring declaration must have an initializer.", - "An_implementation_cannot_be_declared_in_ambient_contexts_1183" : "An implementation cannot be declared in ambient contexts.", - "Modifiers_cannot_appear_here_1184" : "Modifiers cannot appear here.", - "Merge_conflict_marker_encountered_1185" : "Merge conflict marker encountered.", - "A_rest_element_cannot_have_an_initializer_1186" : "A rest element cannot have an initializer.", - "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187" : "A parameter property may not be declared using a binding pattern.", - "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188" : "Only a single variable declaration is allowed in a 'for...of' statement.", - "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189" : "The variable declaration of a 'for...in' statement cannot have an initializer.", - "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190" : "The variable declaration of a 'for...of' statement cannot have an initializer.", - "An_import_declaration_cannot_have_modifiers_1191" : "An import declaration cannot have modifiers.", - "Module_0_has_no_default_export_1192" : "Module '{0}' has no default export.", - "An_export_declaration_cannot_have_modifiers_1193" : "An export declaration cannot have modifiers.", - "Export_declarations_are_not_permitted_in_a_namespace_1194" : "Export declarations are not permitted in a namespace.", - "Catch_clause_variable_cannot_have_a_type_annotation_1196" : "Catch clause variable cannot have a type annotation.", - "Catch_clause_variable_cannot_have_an_initializer_1197" : "Catch clause variable cannot have an initializer.", - "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198" : "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive.", - "Unterminated_Unicode_escape_sequence_1199" : "Unterminated Unicode escape sequence.", - "Line_terminator_not_permitted_before_arrow_1200" : "Line terminator not permitted before arrow.", - "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202" : "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.", - "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203" : "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.", - "Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205" : "Cannot re-export a type when the '--isolatedModules' flag is provided.", - "Decorators_are_not_valid_here_1206" : "Decorators are not valid here.", - "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207" : "Decorators cannot be applied to multiple get/set accessors of the same name.", - "Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided_1208" : "Cannot compile namespaces when the '--isolatedModules' flag is provided.", - "Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided_1209" : "Ambient const enums are not allowed when the '--isolatedModules' flag is provided.", - "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210" : "Invalid use of '{0}'. Class definitions are automatically in strict mode.", - "A_class_declaration_without_the_default_modifier_must_have_a_name_1211" : "A class declaration without the 'default' modifier must have a name.", - "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212" : "Identifier expected. '{0}' is a reserved word in strict mode.", - "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213" : "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.", - "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214" : "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.", - "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215" : "Invalid use of '{0}'. Modules are automatically in strict mode.", - "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216" : "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules.", - "Export_assignment_is_not_supported_when_module_flag_is_system_1218" : "Export assignment is not supported when '--module' flag is 'system'.", - "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219" : "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.", - "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220" : "Generators are only available when targeting ECMAScript 2015 or higher.", - "Generators_are_not_allowed_in_an_ambient_context_1221" : "Generators are not allowed in an ambient context.", - "An_overload_signature_cannot_be_declared_as_a_generator_1222" : "An overload signature cannot be declared as a generator.", - "_0_tag_already_specified_1223" : "'{0}' tag already specified.", - "Signature_0_must_be_a_type_predicate_1224" : "Signature '{0}' must be a type predicate.", - "Cannot_find_parameter_0_1225" : "Cannot find parameter '{0}'.", - "Type_predicate_0_is_not_assignable_to_1_1226" : "Type predicate '{0}' is not assignable to '{1}'.", - "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227" : "Parameter '{0}' is not in the same position as parameter '{1}'.", - "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228" : "A type predicate is only allowed in return type position for functions and methods.", - "A_type_predicate_cannot_reference_a_rest_parameter_1229" : "A type predicate cannot reference a rest parameter.", - "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230" : "A type predicate cannot reference element '{0}' in a binding pattern.", - "An_export_assignment_can_only_be_used_in_a_module_1231" : "An export assignment can only be used in a module.", - "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232" : "An import declaration can only be used in a namespace or module.", - "An_export_declaration_can_only_be_used_in_a_module_1233" : "An export declaration can only be used in a module.", - "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234" : "An ambient module declaration is only allowed at the top level in a file.", - "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235" : "A namespace declaration is only allowed in a namespace or module.", - "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236" : "The return type of a property decorator function must be either 'void' or 'any'.", - "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237" : "The return type of a parameter decorator function must be either 'void' or 'any'.", - "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238" : "Unable to resolve signature of class decorator when called as an expression.", - "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239" : "Unable to resolve signature of parameter decorator when called as an expression.", - "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240" : "Unable to resolve signature of property decorator when called as an expression.", - "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241" : "Unable to resolve signature of method decorator when called as an expression.", - "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242" : "'abstract' modifier can only appear on a class, method, or property declaration.", - "_0_modifier_cannot_be_used_with_1_modifier_1243" : "'{0}' modifier cannot be used with '{1}' modifier.", - "Abstract_methods_can_only_appear_within_an_abstract_class_1244" : "Abstract methods can only appear within an abstract class.", - "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245" : "Method '{0}' cannot have an implementation because it is marked abstract.", - "An_interface_property_cannot_have_an_initializer_1246" : "An interface property cannot have an initializer.", - "A_type_literal_property_cannot_have_an_initializer_1247" : "A type literal property cannot have an initializer.", - "A_class_member_cannot_have_the_0_keyword_1248" : "A class member cannot have the '{0}' keyword.", - "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249" : "A decorator can only decorate a method implementation, not an overload.", - "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" : "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.", - "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251" : "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode.", - "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252" : "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode.", - "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253" : "'{0}' tag cannot be used independently as a top level JSDoc tag.", - "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254" : "A 'const' initializer in an ambient context must be a string or numeric literal.", - "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255" : "A definite assignment assertion '!' is not permitted in this context.", - "with_statements_are_not_allowed_in_an_async_function_block_1300" : "'with' statements are not allowed in an async function block.", - "await_expression_is_only_allowed_within_an_async_function_1308" : "'await' expression is only allowed within an async function.", - "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312" : "'=' can only be used in an object literal property inside a destructuring assignment.", - "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313" : "The body of an 'if' statement cannot be the empty statement.", - "Global_module_exports_may_only_appear_in_module_files_1314" : "Global module exports may only appear in module files.", - "Global_module_exports_may_only_appear_in_declaration_files_1315" : "Global module exports may only appear in declaration files.", - "Global_module_exports_may_only_appear_at_top_level_1316" : "Global module exports may only appear at top level.", - "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317" : "A parameter property cannot be declared using a rest parameter.", - "An_abstract_accessor_cannot_have_an_implementation_1318" : "An abstract accessor cannot have an implementation.", - "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319" : "A default export can only be used in an ECMAScript-style module.", - "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320" : "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.", - "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321" : "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member.", - "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322" : "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member.", - "Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules_1323" : "Dynamic import cannot be used when targeting ECMAScript 2015 modules.", - "Dynamic_import_must_have_one_specifier_as_an_argument_1324" : "Dynamic import must have one specifier as an argument.", - "Specifier_of_dynamic_import_cannot_be_spread_element_1325" : "Specifier of dynamic import cannot be spread element.", - "Dynamic_import_cannot_have_type_arguments_1326" : "Dynamic import cannot have type arguments", - "String_literal_with_double_quotes_expected_1327" : "String literal with double quotes expected.", - "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328" : "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.", - "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" : "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?", - "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330" : "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.", - "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331" : "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.", - "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332" : "A variable whose type is a 'unique symbol' type must be 'const'.", - "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333" : "'unique symbol' types may not be used on a variable declaration with a binding name.", - "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334" : "'unique symbol' types are only allowed on variables in a variable statement.", - "unique_symbol_types_are_not_allowed_here_1335" : "'unique symbol' types are not allowed here.", - "An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336" : "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead.", - "An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead_1337" : "An index signature parameter type cannot be a union type. Consider using a mapped object type instead.", - "infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type_1338" : "'infer' declarations are only permitted in the 'extends' clause of a conditional type.", - "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339" : "Module '{0}' does not refer to a value, but is used as a value here.", - "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_1340" : "Module '{0}' does not refer to a type, but is used as a type here.", - "Type_arguments_cannot_be_used_here_1342" : "Type arguments cannot be used here.", - "The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" : "The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.", - "Duplicate_identifier_0_2300" : "Duplicate identifier '{0}'.", - "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301" : "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.", - "Static_members_cannot_reference_class_type_parameters_2302" : "Static members cannot reference class type parameters.", - "Circular_definition_of_import_alias_0_2303" : "Circular definition of import alias '{0}'.", - "Cannot_find_name_0_2304" : "Cannot find name '{0}'.", - "Module_0_has_no_exported_member_1_2305" : "Module '{0}' has no exported member '{1}'.", - "File_0_is_not_a_module_2306" : "File '{0}' is not a module.", - "Cannot_find_module_0_2307" : "Cannot find module '{0}'.", - "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308" : "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.", - "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309" : "An export assignment cannot be used in a module with other exported elements.", - "Type_0_recursively_references_itself_as_a_base_type_2310" : "Type '{0}' recursively references itself as a base type.", - "A_class_may_only_extend_another_class_2311" : "A class may only extend another class.", - "An_interface_may_only_extend_a_class_or_another_interface_2312" : "An interface may only extend a class or another interface.", - "Type_parameter_0_has_a_circular_constraint_2313" : "Type parameter '{0}' has a circular constraint.", - "Generic_type_0_requires_1_type_argument_s_2314" : "Generic type '{0}' requires {1} type argument(s).", - "Type_0_is_not_generic_2315" : "Type '{0}' is not generic.", - "Global_type_0_must_be_a_class_or_interface_type_2316" : "Global type '{0}' must be a class or interface type.", - "Global_type_0_must_have_1_type_parameter_s_2317" : "Global type '{0}' must have {1} type parameter(s).", - "Cannot_find_global_type_0_2318" : "Cannot find global type '{0}'.", - "Named_property_0_of_types_1_and_2_are_not_identical_2319" : "Named property '{0}' of types '{1}' and '{2}' are not identical.", - "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320" : "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'.", - "Excessive_stack_depth_comparing_types_0_and_1_2321" : "Excessive stack depth comparing types '{0}' and '{1}'.", - "Type_0_is_not_assignable_to_type_1_2322" : "Type '{0}' is not assignable to type '{1}'.", - "Cannot_redeclare_exported_variable_0_2323" : "Cannot redeclare exported variable '{0}'.", - "Property_0_is_missing_in_type_1_2324" : "Property '{0}' is missing in type '{1}'.", - "Property_0_is_private_in_type_1_but_not_in_type_2_2325" : "Property '{0}' is private in type '{1}' but not in type '{2}'.", - "Types_of_property_0_are_incompatible_2326" : "Types of property '{0}' are incompatible.", - "Property_0_is_optional_in_type_1_but_required_in_type_2_2327" : "Property '{0}' is optional in type '{1}' but required in type '{2}'.", - "Types_of_parameters_0_and_1_are_incompatible_2328" : "Types of parameters '{0}' and '{1}' are incompatible.", - "Index_signature_is_missing_in_type_0_2329" : "Index signature is missing in type '{0}'.", - "Index_signatures_are_incompatible_2330" : "Index signatures are incompatible.", - "this_cannot_be_referenced_in_a_module_or_namespace_body_2331" : "'this' cannot be referenced in a module or namespace body.", - "this_cannot_be_referenced_in_current_location_2332" : "'this' cannot be referenced in current location.", - "this_cannot_be_referenced_in_constructor_arguments_2333" : "'this' cannot be referenced in constructor arguments.", - "this_cannot_be_referenced_in_a_static_property_initializer_2334" : "'this' cannot be referenced in a static property initializer.", - "super_can_only_be_referenced_in_a_derived_class_2335" : "'super' can only be referenced in a derived class.", - "super_cannot_be_referenced_in_constructor_arguments_2336" : "'super' cannot be referenced in constructor arguments.", - "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337" : "Super calls are not permitted outside constructors or in nested functions inside constructors.", - "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338" : "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.", - "Property_0_does_not_exist_on_type_1_2339" : "Property '{0}' does not exist on type '{1}'.", - "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340" : "Only public and protected methods of the base class are accessible via the 'super' keyword.", - "Property_0_is_private_and_only_accessible_within_class_1_2341" : "Property '{0}' is private and only accessible within class '{1}'.", - "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342" : "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.", - "This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343" : "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'.", - "Type_0_does_not_satisfy_the_constraint_1_2344" : "Type '{0}' does not satisfy the constraint '{1}'.", - "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345" : "Argument of type '{0}' is not assignable to parameter of type '{1}'.", - "Call_target_does_not_contain_any_signatures_2346" : "Call target does not contain any signatures.", - "Untyped_function_calls_may_not_accept_type_arguments_2347" : "Untyped function calls may not accept type arguments.", - "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348" : "Value of type '{0}' is not callable. Did you mean to include 'new'?", - "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatur_2349" : "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.", - "Only_a_void_function_can_be_called_with_the_new_keyword_2350" : "Only a void function can be called with the 'new' keyword.", - "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351" : "Cannot use 'new' with an expression whose type lacks a call or construct signature.", - "Type_0_cannot_be_converted_to_type_1_2352" : "Type '{0}' cannot be converted to type '{1}'.", - "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353" : "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'.", - "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354" : "This syntax requires an imported helper but module '{0}' cannot be found.", - "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355" : "A function whose declared type is neither 'void' nor 'any' must return a value.", - "An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356" : "An arithmetic operand must be of type 'any', 'number' or an enum type.", - "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357" : "The operand of an increment or decrement operator must be a variable or a property access.", - "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358" : "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.", - "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359" : "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type.", - "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360" : "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.", - "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361" : "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.", - "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362" : "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.", - "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363" : "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.", - "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364" : "The left-hand side of an assignment expression must be a variable or a property access.", - "Operator_0_cannot_be_applied_to_types_1_and_2_2365" : "Operator '{0}' cannot be applied to types '{1}' and '{2}'.", - "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366" : "Function lacks ending return statement and return type does not include 'undefined'.", - "Type_parameter_name_cannot_be_0_2368" : "Type parameter name cannot be '{0}'.", - "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369" : "A parameter property is only allowed in a constructor implementation.", - "A_rest_parameter_must_be_of_an_array_type_2370" : "A rest parameter must be of an array type.", - "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371" : "A parameter initializer is only allowed in a function or constructor implementation.", - "Parameter_0_cannot_be_referenced_in_its_initializer_2372" : "Parameter '{0}' cannot be referenced in its initializer.", - "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373" : "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it.", - "Duplicate_string_index_signature_2374" : "Duplicate string index signature.", - "Duplicate_number_index_signature_2375" : "Duplicate number index signature.", - "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376" : "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties.", - "Constructors_for_derived_classes_must_contain_a_super_call_2377" : "Constructors for derived classes must contain a 'super' call.", - "A_get_accessor_must_return_a_value_2378" : "A 'get' accessor must return a value.", - "Getter_and_setter_accessors_do_not_agree_in_visibility_2379" : "Getter and setter accessors do not agree in visibility.", - "get_and_set_accessor_must_have_the_same_type_2380" : "'get' and 'set' accessor must have the same type.", - "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381" : "A signature with an implementation cannot use a string literal type.", - "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382" : "Specialized overload signature is not assignable to any non-specialized signature.", - "Overload_signatures_must_all_be_exported_or_non_exported_2383" : "Overload signatures must all be exported or non-exported.", - "Overload_signatures_must_all_be_ambient_or_non_ambient_2384" : "Overload signatures must all be ambient or non-ambient.", - "Overload_signatures_must_all_be_public_private_or_protected_2385" : "Overload signatures must all be public, private or protected.", - "Overload_signatures_must_all_be_optional_or_required_2386" : "Overload signatures must all be optional or required.", - "Function_overload_must_be_static_2387" : "Function overload must be static.", - "Function_overload_must_not_be_static_2388" : "Function overload must not be static.", - "Function_implementation_name_must_be_0_2389" : "Function implementation name must be '{0}'.", - "Constructor_implementation_is_missing_2390" : "Constructor implementation is missing.", - "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391" : "Function implementation is missing or not immediately following the declaration.", - "Multiple_constructor_implementations_are_not_allowed_2392" : "Multiple constructor implementations are not allowed.", - "Duplicate_function_implementation_2393" : "Duplicate function implementation.", - "Overload_signature_is_not_compatible_with_function_implementation_2394" : "Overload signature is not compatible with function implementation.", - "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395" : "Individual declarations in merged declaration '{0}' must be all exported or all local.", - "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396" : "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.", - "Declaration_name_conflicts_with_built_in_global_identifier_0_2397" : "Declaration name conflicts with built-in global identifier '{0}'.", - "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399" : "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.", - "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400" : "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.", - "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401" : "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference.", - "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402" : "Expression resolves to '_super' that compiler uses to capture base class reference.", - "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" : "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.", - "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404" : "The left-hand side of a 'for...in' statement cannot use a type annotation.", - "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405" : "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.", - "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406" : "The left-hand side of a 'for...in' statement must be a variable or a property access.", - "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_2407" : "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'.", - "Setters_cannot_return_a_value_2408" : "Setters cannot return a value.", - "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409" : "Return type of constructor signature must be assignable to the instance type of the class.", - "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410" : "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.", - "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411" : "Property '{0}' of type '{1}' is not assignable to string index type '{2}'.", - "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412" : "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'.", - "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413" : "Numeric index type '{0}' is not assignable to string index type '{1}'.", - "Class_name_cannot_be_0_2414" : "Class name cannot be '{0}'.", - "Class_0_incorrectly_extends_base_class_1_2415" : "Class '{0}' incorrectly extends base class '{1}'.", - "Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416" : "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.", - "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417" : "Class static side '{0}' incorrectly extends base class static side '{1}'.", - "Class_0_incorrectly_implements_interface_1_2420" : "Class '{0}' incorrectly implements interface '{1}'.", - "A_class_may_only_implement_another_class_or_interface_2422" : "A class may only implement another class or interface.", - "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423" : "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor.", - "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424" : "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property.", - "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425" : "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function.", - "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426" : "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function.", - "Interface_name_cannot_be_0_2427" : "Interface name cannot be '{0}'.", - "All_declarations_of_0_must_have_identical_type_parameters_2428" : "All declarations of '{0}' must have identical type parameters.", - "Interface_0_incorrectly_extends_interface_1_2430" : "Interface '{0}' incorrectly extends interface '{1}'.", - "Enum_name_cannot_be_0_2431" : "Enum name cannot be '{0}'.", - "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432" : "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.", - "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433" : "A namespace declaration cannot be in a different file from a class or function with which it is merged.", - "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434" : "A namespace declaration cannot be located prior to a class or function with which it is merged.", - "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435" : "Ambient modules cannot be nested in other modules or namespaces.", - "Ambient_module_declaration_cannot_specify_relative_module_name_2436" : "Ambient module declaration cannot specify relative module name.", - "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437" : "Module '{0}' is hidden by a local declaration with the same name.", - "Import_name_cannot_be_0_2438" : "Import name cannot be '{0}'.", - "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439" : "Import or export declaration in an ambient module declaration cannot reference module through relative module name.", - "Import_declaration_conflicts_with_local_declaration_of_0_2440" : "Import declaration conflicts with local declaration of '{0}'.", - "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441" : "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module.", - "Types_have_separate_declarations_of_a_private_property_0_2442" : "Types have separate declarations of a private property '{0}'.", - "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443" : "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'.", - "Property_0_is_protected_in_type_1_but_public_in_type_2_2444" : "Property '{0}' is protected in type '{1}' but public in type '{2}'.", - "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445" : "Property '{0}' is protected and only accessible within class '{1}' and its subclasses.", - "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446" : "Property '{0}' is protected and only accessible through an instance of class '{1}'.", - "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447" : "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead.", - "Block_scoped_variable_0_used_before_its_declaration_2448" : "Block-scoped variable '{0}' used before its declaration.", - "Class_0_used_before_its_declaration_2449" : "Class '{0}' used before its declaration.", - "Enum_0_used_before_its_declaration_2450" : "Enum '{0}' used before its declaration.", - "Cannot_redeclare_block_scoped_variable_0_2451" : "Cannot redeclare block-scoped variable '{0}'.", - "An_enum_member_cannot_have_a_numeric_name_2452" : "An enum member cannot have a numeric name.", - "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453" : "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly.", - "Variable_0_is_used_before_being_assigned_2454" : "Variable '{0}' is used before being assigned.", - "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455" : "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'.", - "Type_alias_0_circularly_references_itself_2456" : "Type alias '{0}' circularly references itself.", - "Type_alias_name_cannot_be_0_2457" : "Type alias name cannot be '{0}'.", - "An_AMD_module_cannot_have_multiple_name_assignments_2458" : "An AMD module cannot have multiple name assignments.", - "Type_0_has_no_property_1_and_no_string_index_signature_2459" : "Type '{0}' has no property '{1}' and no string index signature.", - "Type_0_has_no_property_1_2460" : "Type '{0}' has no property '{1}'.", - "Type_0_is_not_an_array_type_2461" : "Type '{0}' is not an array type.", - "A_rest_element_must_be_last_in_a_destructuring_pattern_2462" : "A rest element must be last in a destructuring pattern.", - "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463" : "A binding pattern parameter cannot be optional in an implementation signature.", - "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464" : "A computed property name must be of type 'string', 'number', 'symbol', or 'any'.", - "this_cannot_be_referenced_in_a_computed_property_name_2465" : "'this' cannot be referenced in a computed property name.", - "super_cannot_be_referenced_in_a_computed_property_name_2466" : "'super' cannot be referenced in a computed property name.", - "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467" : "A computed property name cannot reference a type parameter from its containing type.", - "Cannot_find_global_value_0_2468" : "Cannot find global value '{0}'.", - "The_0_operator_cannot_be_applied_to_type_symbol_2469" : "The '{0}' operator cannot be applied to type 'symbol'.", - "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470" : "'Symbol' reference does not refer to the global Symbol constructor object.", - "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471" : "A computed property name of the form '{0}' must be of type 'symbol'.", - "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472" : "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher.", - "Enum_declarations_must_all_be_const_or_non_const_2473" : "Enum declarations must all be const or non-const.", - "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474" : "In 'const' enum declarations member initializer must be constant expression.", - "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475" : "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.", - "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476" : "A const enum member can only be accessed using a string literal.", - "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477" : "'const' enum member initializer was evaluated to a non-finite value.", - "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478" : "'const' enum member initializer was evaluated to disallowed value 'NaN'.", - "Property_0_does_not_exist_on_const_enum_1_2479" : "Property '{0}' does not exist on 'const' enum '{1}'.", - "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480" : "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", - "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481" : "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.", - "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483" : "The left-hand side of a 'for...of' statement cannot use a type annotation.", - "Export_declaration_conflicts_with_exported_declaration_of_0_2484" : "Export declaration conflicts with exported declaration of '{0}'.", - "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487" : "The left-hand side of a 'for...of' statement must be a variable or a property access.", - "Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488" : "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator.", - "An_iterator_must_have_a_next_method_2489" : "An iterator must have a 'next()' method.", - "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490" : "The type returned by the 'next()' method of an iterator must have a 'value' property.", - "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491" : "The left-hand side of a 'for...in' statement cannot be a destructuring pattern.", - "Cannot_redeclare_identifier_0_in_catch_clause_2492" : "Cannot redeclare identifier '{0}' in catch clause.", - "Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2_2493" : "Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'.", - "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494" : "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher.", - "Type_0_is_not_an_array_type_or_a_string_type_2495" : "Type '{0}' is not an array type or a string type.", - "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496" : "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression.", - "Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497" : "Module '{0}' resolves to a non-module entity and cannot be imported using this construct.", - "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498" : "Module '{0}' uses 'export =' and cannot be used with 'export *'.", - "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499" : "An interface can only extend an identifier/qualified-name with optional type arguments.", - "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500" : "A class can only implement an identifier/qualified-name with optional type arguments.", - "A_rest_element_cannot_contain_a_binding_pattern_2501" : "A rest element cannot contain a binding pattern.", - "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502" : "'{0}' is referenced directly or indirectly in its own type annotation.", - "Cannot_find_namespace_0_2503" : "Cannot find namespace '{0}'.", - "Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504" : "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.", - "A_generator_cannot_have_a_void_type_annotation_2505" : "A generator cannot have a 'void' type annotation.", - "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506" : "'{0}' is referenced directly or indirectly in its own base expression.", - "Type_0_is_not_a_constructor_function_type_2507" : "Type '{0}' is not a constructor function type.", - "No_base_constructor_has_the_specified_number_of_type_arguments_2508" : "No base constructor has the specified number of type arguments.", - "Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509" : "Base constructor return type '{0}' is not a class or interface type.", - "Base_constructors_must_all_have_the_same_return_type_2510" : "Base constructors must all have the same return type.", - "Cannot_create_an_instance_of_an_abstract_class_2511" : "Cannot create an instance of an abstract class.", - "Overload_signatures_must_all_be_abstract_or_non_abstract_2512" : "Overload signatures must all be abstract or non-abstract.", - "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513" : "Abstract method '{0}' in class '{1}' cannot be accessed via super expression.", - "Classes_containing_abstract_methods_must_be_marked_abstract_2514" : "Classes containing abstract methods must be marked abstract.", - "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515" : "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'.", - "All_declarations_of_an_abstract_method_must_be_consecutive_2516" : "All declarations of an abstract method must be consecutive.", - "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517" : "Cannot assign an abstract constructor type to a non-abstract constructor type.", - "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518" : "A 'this'-based type guard is not compatible with a parameter-based type guard.", - "An_async_iterator_must_have_a_next_method_2519" : "An async iterator must have a 'next()' method.", - "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520" : "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.", - "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521" : "Expression resolves to variable declaration '{0}' that compiler uses to support async functions.", - "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522" : "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method.", - "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523" : "'yield' expressions cannot be used in a parameter initializer.", - "await_expressions_cannot_be_used_in_a_parameter_initializer_2524" : "'await' expressions cannot be used in a parameter initializer.", - "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525" : "Initializer provides no value for this binding element and the binding element has no default value.", - "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526" : "A 'this' type is available only in a non-static member of a class or interface.", - "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" : "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.", - "A_module_cannot_have_multiple_default_exports_2528" : "A module cannot have multiple default exports.", - "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529" : "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions.", - "Property_0_is_incompatible_with_index_signature_2530" : "Property '{0}' is incompatible with index signature.", - "Object_is_possibly_null_2531" : "Object is possibly 'null'.", - "Object_is_possibly_undefined_2532" : "Object is possibly 'undefined'.", - "Object_is_possibly_null_or_undefined_2533" : "Object is possibly 'null' or 'undefined'.", - "A_function_returning_never_cannot_have_a_reachable_end_point_2534" : "A function returning 'never' cannot have a reachable end point.", - "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535" : "Enum type '{0}' has members with initializers that are not literals.", - "Type_0_cannot_be_used_to_index_type_1_2536" : "Type '{0}' cannot be used to index type '{1}'.", - "Type_0_has_no_matching_index_signature_for_type_1_2537" : "Type '{0}' has no matching index signature for type '{1}'.", - "Type_0_cannot_be_used_as_an_index_type_2538" : "Type '{0}' cannot be used as an index type.", - "Cannot_assign_to_0_because_it_is_not_a_variable_2539" : "Cannot assign to '{0}' because it is not a variable.", - "Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property_2540" : "Cannot assign to '{0}' because it is a constant or a read-only property.", - "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541" : "The target of an assignment must be a variable or a property access.", - "Index_signature_in_type_0_only_permits_reading_2542" : "Index signature in type '{0}' only permits reading.", - "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543" : "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference.", - "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544" : "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference.", - "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545" : "A mixin class must have a constructor with a single rest parameter of type 'any[]'.", - "Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1_2546" : "Property '{0}' has conflicting declarations and is inaccessible in type '{1}'.", - "The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547" : "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.", - "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548" : "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.", - "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" : "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.", - "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550" : "Generic type instantiation is excessively deep and possibly infinite.", - "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551" : "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?", - "Cannot_find_name_0_Did_you_mean_1_2552" : "Cannot find name '{0}'. Did you mean '{1}'?", - "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553" : "Computed values are not permitted in an enum with string valued members.", - "Expected_0_arguments_but_got_1_2554" : "Expected {0} arguments, but got {1}.", - "Expected_at_least_0_arguments_but_got_1_2555" : "Expected at least {0} arguments, but got {1}.", - "Expected_0_arguments_but_got_1_or_more_2556" : "Expected {0} arguments, but got {1} or more.", - "Expected_at_least_0_arguments_but_got_1_or_more_2557" : "Expected at least {0} arguments, but got {1} or more.", - "Expected_0_type_arguments_but_got_1_2558" : "Expected {0} type arguments, but got {1}.", - "Type_0_has_no_properties_in_common_with_type_1_2559" : "Type '{0}' has no properties in common with type '{1}'.", - "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560" : "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?", - "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561" : "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?", - "Base_class_expressions_cannot_reference_class_type_parameters_2562" : "Base class expressions cannot reference class type parameters.", - "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563" : "The containing function or module body is too large for control flow analysis.", - "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564" : "Property '{0}' has no initializer and is not definitely assigned in the constructor.", - "Property_0_is_used_before_being_assigned_2565" : "Property '{0}' is used before being assigned.", - "A_rest_element_cannot_have_a_property_name_2566" : "A rest element cannot have a property name.", - "Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567" : "Enum declarations can only merge with namespace or other enum declarations.", - "Type_0_is_not_an_array_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators_2568" : "Type '{0}' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators.", - "Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" : "Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.", - "Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" : "Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?", - "JSX_element_attributes_type_0_may_not_be_a_union_type_2600" : "JSX element attributes type '{0}' may not be a union type.", - "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601" : "The return type of a JSX element constructor must return an object type.", - "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602" : "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.", - "Property_0_in_type_1_is_not_assignable_to_type_2_2603" : "Property '{0}' in type '{1}' is not assignable to type '{2}'.", - "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604" : "JSX element type '{0}' does not have any construct or call signatures.", - "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605" : "JSX element type '{0}' is not a constructor function for JSX elements.", - "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606" : "Property '{0}' of JSX spread attribute is not assignable to target property.", - "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607" : "JSX element class does not support attributes because it does not have a '{0}' property.", - "The_global_type_JSX_0_may_not_have_more_than_one_property_2608" : "The global type 'JSX.{0}' may not have more than one property.", - "JSX_spread_child_must_be_an_array_type_2609" : "JSX spread child must be an array type.", - "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649" : "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.", - "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651" : "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.", - "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652" : "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.", - "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653" : "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'.", - "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654" : "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.", - "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656" : "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition.", - "JSX_expressions_must_have_one_parent_element_2657" : "JSX expressions must have one parent element.", - "Type_0_provides_no_match_for_the_signature_1_2658" : "Type '{0}' provides no match for the signature '{1}'.", - "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659" : "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher.", - "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660" : "'super' can only be referenced in members of derived classes or object literal expressions.", - "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661" : "Cannot export '{0}'. Only local declarations can be exported from a module.", - "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662" : "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?", - "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663" : "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?", - "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664" : "Invalid module name in augmentation, module '{0}' cannot be found.", - "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665" : "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented.", - "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666" : "Exports and export assignments are not permitted in module augmentations.", - "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667" : "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.", - "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668" : "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible.", - "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669" : "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.", - "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670" : "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.", - "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671" : "Cannot augment module '{0}' because it resolves to a non-module entity.", - "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672" : "Cannot assign a '{0}' constructor type to a '{1}' constructor type.", - "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673" : "Constructor of class '{0}' is private and only accessible within the class declaration.", - "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674" : "Constructor of class '{0}' is protected and only accessible within the class declaration.", - "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675" : "Cannot extend a class '{0}'. Class constructor is marked as private.", - "Accessors_must_both_be_abstract_or_non_abstract_2676" : "Accessors must both be abstract or non-abstract.", - "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677" : "A type predicate's type must be assignable to its parameter's type.", - "Type_0_is_not_comparable_to_type_1_2678" : "Type '{0}' is not comparable to type '{1}'.", - "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679" : "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'.", - "A_0_parameter_must_be_the_first_parameter_2680" : "A '{0}' parameter must be the first parameter.", - "A_constructor_cannot_have_a_this_parameter_2681" : "A constructor cannot have a 'this' parameter.", - "get_and_set_accessor_must_have_the_same_this_type_2682" : "'get' and 'set' accessor must have the same 'this' type.", - "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683" : "'this' implicitly has type 'any' because it does not have a type annotation.", - "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684" : "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'.", - "The_this_types_of_each_signature_are_incompatible_2685" : "The 'this' types of each signature are incompatible.", - "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686" : "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.", - "All_declarations_of_0_must_have_identical_modifiers_2687" : "All declarations of '{0}' must have identical modifiers.", - "Cannot_find_type_definition_file_for_0_2688" : "Cannot find type definition file for '{0}'.", - "Cannot_extend_an_interface_0_Did_you_mean_implements_2689" : "Cannot extend an interface '{0}'. Did you mean 'implements'?", - "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691" : "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.", - "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692" : "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible.", - "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693" : "'{0}' only refers to a type, but is being used as a value here.", - "Namespace_0_has_no_exported_member_1_2694" : "Namespace '{0}' has no exported member '{1}'.", - "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695" : "Left side of comma operator is unused and has no side effects.", - "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696" : "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?", - "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697" : "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.", - "Spread_types_may_only_be_created_from_object_types_2698" : "Spread types may only be created from object types.", - "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699" : "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.", - "Rest_types_may_only_be_created_from_object_types_2700" : "Rest types may only be created from object types.", - "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701" : "The target of an object rest assignment must be a variable or a property access.", - "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702" : "'{0}' only refers to a type, but is being used as a namespace here.", - "The_operand_of_a_delete_operator_must_be_a_property_reference_2703" : "The operand of a delete operator must be a property reference.", - "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704" : "The operand of a delete operator cannot be a read-only property.", - "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705" : "An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.", - "Required_type_parameters_may_not_follow_optional_type_parameters_2706" : "Required type parameters may not follow optional type parameters.", - "Generic_type_0_requires_between_1_and_2_type_arguments_2707" : "Generic type '{0}' requires between {1} and {2} type arguments.", - "Cannot_use_namespace_0_as_a_value_2708" : "Cannot use namespace '{0}' as a value.", - "Cannot_use_namespace_0_as_a_type_2709" : "Cannot use namespace '{0}' as a type.", - "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" : "'{0}' are specified twice. The attribute named '{0}' will be overwritten.", - "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711" : "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.", - "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712" : "A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.", - "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713" : "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?", - "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714" : "The expression of an export assignment must be an identifier or qualified name in an ambient context.", - "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" : "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.", - "Type_parameter_0_has_a_circular_default_2716" : "Type parameter '{0}' has a circular default.", - "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717" : "Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'.", - "Duplicate_declaration_0_2718" : "Duplicate declaration '{0}'.", - "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719" : "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.", - "Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclas_2720" : "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?", - "Cannot_invoke_an_object_which_is_possibly_null_2721" : "Cannot invoke an object which is possibly 'null'.", - "Cannot_invoke_an_object_which_is_possibly_undefined_2722" : "Cannot invoke an object which is possibly 'undefined'.", - "Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723" : "Cannot invoke an object which is possibly 'null' or 'undefined'.", - "Module_0_has_no_exported_member_1_Did_you_mean_2_2724" : "Module '{0}' has no exported member '{1}'. Did you mean '{2}'?", - "Import_declaration_0_is_using_private_name_1_4000" : "Import declaration '{0}' is using private name '{1}'.", - "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002" : "Type parameter '{0}' of exported class has or is using private name '{1}'.", - "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004" : "Type parameter '{0}' of exported interface has or is using private name '{1}'.", - "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006" : "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.", - "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" : "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.", - "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010" : "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'.", - "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012" : "Type parameter '{0}' of public method from exported class has or is using private name '{1}'.", - "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014" : "Type parameter '{0}' of method from exported interface has or is using private name '{1}'.", - "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016" : "Type parameter '{0}' of exported function has or is using private name '{1}'.", - "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019" : "Implements clause of exported class '{0}' has or is using private name '{1}'.", - "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020" : "'extends' clause of exported class '{0}' has or is using private name '{1}'.", - "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022" : "'extends' clause of exported interface '{0}' has or is using private name '{1}'.", - "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023" : "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named.", - "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024" : "Exported variable '{0}' has or is using name '{1}' from private module '{2}'.", - "Exported_variable_0_has_or_is_using_private_name_1_4025" : "Exported variable '{0}' has or is using private name '{1}'.", - "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026" : "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027" : "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'.", - "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028" : "Public static property '{0}' of exported class has or is using private name '{1}'.", - "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029" : "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030" : "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'.", - "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031" : "Public property '{0}' of exported class has or is using private name '{1}'.", - "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032" : "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'.", - "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033" : "Property '{0}' of exported interface has or is using private name '{1}'.", - "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034" : "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.", - "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035" : "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.", - "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036" : "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.", - "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037" : "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.", - "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038" : "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039" : "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.", - "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040" : "Return type of public static getter '{0}' from exported class has or is using private name '{1}'.", - "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041" : "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042" : "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.", - "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043" : "Return type of public getter '{0}' from exported class has or is using private name '{1}'.", - "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044" : "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'.", - "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045" : "Return type of constructor signature from exported interface has or is using private name '{0}'.", - "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046" : "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'.", - "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047" : "Return type of call signature from exported interface has or is using private name '{0}'.", - "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048" : "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'.", - "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049" : "Return type of index signature from exported interface has or is using private name '{0}'.", - "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050" : "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named.", - "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051" : "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'.", - "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052" : "Return type of public static method from exported class has or is using private name '{0}'.", - "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053" : "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named.", - "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054" : "Return type of public method from exported class has or is using name '{0}' from private module '{1}'.", - "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055" : "Return type of public method from exported class has or is using private name '{0}'.", - "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056" : "Return type of method from exported interface has or is using name '{0}' from private module '{1}'.", - "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057" : "Return type of method from exported interface has or is using private name '{0}'.", - "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058" : "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named.", - "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059" : "Return type of exported function has or is using name '{0}' from private module '{1}'.", - "Return_type_of_exported_function_has_or_is_using_private_name_0_4060" : "Return type of exported function has or is using private name '{0}'.", - "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061" : "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062" : "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063" : "Parameter '{0}' of constructor from exported class has or is using private name '{1}'.", - "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064" : "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065" : "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.", - "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066" : "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067" : "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'.", - "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068" : "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069" : "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070" : "Parameter '{0}' of public static method from exported class has or is using private name '{1}'.", - "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071" : "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072" : "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073" : "Parameter '{0}' of public method from exported class has or is using private name '{1}'.", - "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074" : "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075" : "Parameter '{0}' of method from exported interface has or is using private name '{1}'.", - "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076" : "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named.", - "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077" : "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078" : "Parameter '{0}' of exported function has or is using private name '{1}'.", - "Exported_type_alias_0_has_or_is_using_private_name_1_4081" : "Exported type alias '{0}' has or is using private name '{1}'.", - "Default_export_of_the_module_has_or_is_using_private_name_0_4082" : "Default export of the module has or is using private name '{0}'.", - "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083" : "Type parameter '{0}' of exported type alias has or is using private name '{1}'.", - "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090" : "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict.", - "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091" : "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.", - "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092" : "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.", - "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094" : "Property '{0}' of exported class expression may not be private or protected.", - "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095" : "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096" : "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.", - "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097" : "Public static method '{0}' of exported class has or is using private name '{1}'.", - "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098" : "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.", - "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099" : "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.", - "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100" : "Public method '{0}' of exported class has or is using private name '{1}'.", - "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101" : "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.", - "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102" : "Method '{0}' of exported interface has or is using private name '{1}'.", - "The_current_host_does_not_support_the_0_option_5001" : "The current host does not support the '{0}' option.", - "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009" : "Cannot find the common subdirectory path for the input files.", - "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010" : "File specification cannot end in a recursive directory wildcard ('**'): '{0}'.", - "Cannot_read_file_0_Colon_1_5012" : "Cannot read file '{0}': {1}.", - "Failed_to_parse_file_0_Colon_1_5014" : "Failed to parse file '{0}': {1}.", - "Unknown_compiler_option_0_5023" : "Unknown compiler option '{0}'.", - "Compiler_option_0_requires_a_value_of_type_1_5024" : "Compiler option '{0}' requires a value of type {1}.", - "Could_not_write_file_0_Colon_1_5033" : "Could not write file '{0}': {1}.", - "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042" : "Option 'project' cannot be mixed with source files on a command line.", - "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047" : "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher.", - "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051" : "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided.", - "Option_0_cannot_be_specified_without_specifying_option_1_5052" : "Option '{0}' cannot be specified without specifying option '{1}'.", - "Option_0_cannot_be_specified_with_option_1_5053" : "Option '{0}' cannot be specified with option '{1}'.", - "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054" : "A 'tsconfig.json' file is already defined at: '{0}'.", - "Cannot_write_file_0_because_it_would_overwrite_input_file_5055" : "Cannot write file '{0}' because it would overwrite input file.", - "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056" : "Cannot write file '{0}' because it would be overwritten by multiple input files.", - "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057" : "Cannot find a tsconfig.json file at the specified directory: '{0}'.", - "The_specified_path_does_not_exist_Colon_0_5058" : "The specified path does not exist: '{0}'.", - "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059" : "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier.", - "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060" : "Option 'paths' cannot be used without specifying '--baseUrl' option.", - "Pattern_0_can_have_at_most_one_Asterisk_character_5061" : "Pattern '{0}' can have at most one '*' character.", - "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062" : "Substitution '{0}' in pattern '{1}' in can have at most one '*' character.", - "Substitutions_for_pattern_0_should_be_an_array_5063" : "Substitutions for pattern '{0}' should be an array.", - "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064" : "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'.", - "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065" : "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'.", - "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066" : "Substitutions for pattern '{0}' shouldn't be an empty array.", - "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067" : "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name.", - "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068" : "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.", - "Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069" : "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'.", - "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" : "Generates a sourcemap for each corresponding '.d.ts' file.", - "Concatenate_and_emit_output_to_single_file_6001" : "Concatenate and emit output to single file.", - "Generates_corresponding_d_ts_file_6002" : "Generates corresponding '.d.ts' file.", - "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003" : "Specify the location where debugger should locate map files instead of generated locations.", - "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004" : "Specify the location where debugger should locate TypeScript files instead of source locations.", - "Watch_input_files_6005" : "Watch input files.", - "Redirect_output_structure_to_the_directory_6006" : "Redirect output structure to the directory.", - "Do_not_erase_const_enum_declarations_in_generated_code_6007" : "Do not erase const enum declarations in generated code.", - "Do_not_emit_outputs_if_any_errors_were_reported_6008" : "Do not emit outputs if any errors were reported.", - "Do_not_emit_comments_to_output_6009" : "Do not emit comments to output.", - "Do_not_emit_outputs_6010" : "Do not emit outputs.", - "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011" : "Allow default imports from modules with no default export. This does not affect code emit, just typechecking.", - "Skip_type_checking_of_declaration_files_6012" : "Skip type checking of declaration files.", - "Do_not_resolve_the_real_path_of_symlinks_6013" : "Do not resolve the real path of symlinks.", - "Only_emit_d_ts_declaration_files_6014" : "Only emit '.d.ts' declaration files.", - "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_or_ESNEXT_6015" : "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'.", - "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016" : "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.", - "Print_this_message_6017" : "Print this message.", - "Print_the_compiler_s_version_6019" : "Print the compiler's version.", - "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" : "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.", - "Syntax_Colon_0_6023" : "Syntax: {0}", - "options_6024" : "options", - "file_6025" : "file", - "Examples_Colon_0_6026" : "Examples: {0}", - "Options_Colon_6027" : "Options:", - "Version_0_6029" : "Version {0}", - "Insert_command_line_options_and_files_from_a_file_6030" : "Insert command line options and files from a file.", - "Starting_compilation_in_watch_mode_6031" : "Starting compilation in watch mode...", - "File_change_detected_Starting_incremental_compilation_6032" : "File change detected. Starting incremental compilation...", - "KIND_6034" : "KIND", - "FILE_6035" : "FILE", - "VERSION_6036" : "VERSION", - "LOCATION_6037" : "LOCATION", - "DIRECTORY_6038" : "DIRECTORY", - "STRATEGY_6039" : "STRATEGY", - "FILE_OR_DIRECTORY_6040" : "FILE OR DIRECTORY", - "Generates_corresponding_map_file_6043" : "Generates corresponding '.map' file.", - "Compiler_option_0_expects_an_argument_6044" : "Compiler option '{0}' expects an argument.", - "Unterminated_quoted_string_in_response_file_0_6045" : "Unterminated quoted string in response file '{0}'.", - "Argument_for_0_option_must_be_Colon_1_6046" : "Argument for '{0}' option must be: {1}.", - "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048" : "Locale must be of the form or -. For example '{0}' or '{1}'.", - "Unsupported_locale_0_6049" : "Unsupported locale '{0}'.", - "Unable_to_open_file_0_6050" : "Unable to open file '{0}'.", - "Corrupted_locale_file_0_6051" : "Corrupted locale file {0}.", - "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052" : "Raise error on expressions and declarations with an implied 'any' type.", - "File_0_not_found_6053" : "File '{0}' not found.", - "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054" : "File '{0}' has unsupported extension. The only supported extensions are {1}.", - "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055" : "Suppress noImplicitAny errors for indexing objects lacking index signatures.", - "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056" : "Do not emit declarations for code that has an '@internal' annotation.", - "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058" : "Specify the root directory of input files. Use to control the output directory structure with --outDir.", - "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059" : "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files.", - "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060" : "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).", - "NEWLINE_6061" : "NEWLINE", - "Option_0_can_only_be_specified_in_tsconfig_json_file_6064" : "Option '{0}' can only be specified in 'tsconfig.json' file.", - "Enables_experimental_support_for_ES7_decorators_6065" : "Enables experimental support for ES7 decorators.", - "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066" : "Enables experimental support for emitting type metadata for decorators.", - "Enables_experimental_support_for_ES7_async_functions_6068" : "Enables experimental support for ES7 async functions.", - "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069" : "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).", - "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070" : "Initializes a TypeScript project and creates a tsconfig.json file.", - "Successfully_created_a_tsconfig_json_file_6071" : "Successfully created a tsconfig.json file.", - "Suppress_excess_property_checks_for_object_literals_6072" : "Suppress excess property checks for object literals.", - "Stylize_errors_and_messages_using_color_and_context_experimental_6073" : "Stylize errors and messages using color and context (experimental).", - "Do_not_report_errors_on_unused_labels_6074" : "Do not report errors on unused labels.", - "Report_error_when_not_all_code_paths_in_function_return_a_value_6075" : "Report error when not all code paths in function return a value.", - "Report_errors_for_fallthrough_cases_in_switch_statement_6076" : "Report errors for fallthrough cases in switch statement.", - "Do_not_report_errors_on_unreachable_code_6077" : "Do not report errors on unreachable code.", - "Disallow_inconsistently_cased_references_to_the_same_file_6078" : "Disallow inconsistently-cased references to the same file.", - "Specify_library_files_to_be_included_in_the_compilation_6079" : "Specify library files to be included in the compilation.", - "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080" : "Specify JSX code generation: 'preserve', 'react-native', or 'react'.", - "File_0_has_an_unsupported_extension_so_skipping_it_6081" : "File '{0}' has an unsupported extension, so skipping it.", - "Only_amd_and_system_modules_are_supported_alongside_0_6082" : "Only 'amd' and 'system' modules are supported alongside --{0}.", - "Base_directory_to_resolve_non_absolute_module_names_6083" : "Base directory to resolve non-absolute module names.", - "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084" : "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit", - "Enable_tracing_of_the_name_resolution_process_6085" : "Enable tracing of the name resolution process.", - "Resolving_module_0_from_1_6086" : "======== Resolving module '{0}' from '{1}'. ========", - "Explicitly_specified_module_resolution_kind_Colon_0_6087" : "Explicitly specified module resolution kind: '{0}'.", - "Module_resolution_kind_is_not_specified_using_0_6088" : "Module resolution kind is not specified, using '{0}'.", - "Module_name_0_was_successfully_resolved_to_1_6089" : "======== Module name '{0}' was successfully resolved to '{1}'. ========", - "Module_name_0_was_not_resolved_6090" : "======== Module name '{0}' was not resolved. ========", - "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091" : "'paths' option is specified, looking for a pattern to match module name '{0}'.", - "Module_name_0_matched_pattern_1_6092" : "Module name '{0}', matched pattern '{1}'.", - "Trying_substitution_0_candidate_module_location_Colon_1_6093" : "Trying substitution '{0}', candidate module location: '{1}'.", - "Resolving_module_name_0_relative_to_base_url_1_2_6094" : "Resolving module name '{0}' relative to base url '{1}' - '{2}'.", - "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095" : "Loading module as file / folder, candidate module location '{0}', target file type '{1}'.", - "File_0_does_not_exist_6096" : "File '{0}' does not exist.", - "File_0_exist_use_it_as_a_name_resolution_result_6097" : "File '{0}' exist - use it as a name resolution result.", - "Loading_module_0_from_node_modules_folder_target_file_type_1_6098" : "Loading module '{0}' from 'node_modules' folder, target file type '{1}'.", - "Found_package_json_at_0_6099" : "Found 'package.json' at '{0}'.", - "package_json_does_not_have_a_0_field_6100" : "'package.json' does not have a '{0}' field.", - "package_json_has_0_field_1_that_references_2_6101" : "'package.json' has '{0}' field '{1}' that references '{2}'.", - "Allow_javascript_files_to_be_compiled_6102" : "Allow javascript files to be compiled.", - "Option_0_should_have_array_of_strings_as_a_value_6103" : "Option '{0}' should have array of strings as a value.", - "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104" : "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'.", - "Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105" : "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.", - "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106" : "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'.", - "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" : "'rootDirs' option is set, using it to resolve relative module name '{0}'.", - "Longest_matching_prefix_for_0_is_1_6108" : "Longest matching prefix for '{0}' is '{1}'.", - "Loading_0_from_the_root_dir_1_candidate_location_2_6109" : "Loading '{0}' from the root dir '{1}', candidate location '{2}'.", - "Trying_other_entries_in_rootDirs_6110" : "Trying other entries in 'rootDirs'.", - "Module_resolution_using_rootDirs_has_failed_6111" : "Module resolution using 'rootDirs' has failed.", - "Do_not_emit_use_strict_directives_in_module_output_6112" : "Do not emit 'use strict' directives in module output.", - "Enable_strict_null_checks_6113" : "Enable strict null checks.", - "Unknown_option_excludes_Did_you_mean_exclude_6114" : "Unknown option 'excludes'. Did you mean 'exclude'?", - "Raise_error_on_this_expressions_with_an_implied_any_type_6115" : "Raise error on 'this' expressions with an implied 'any' type.", - "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116" : "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========", - "Resolving_using_primary_search_paths_6117" : "Resolving using primary search paths...", - "Resolving_from_node_modules_folder_6118" : "Resolving from node_modules folder...", - "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119" : "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========", - "Type_reference_directive_0_was_not_resolved_6120" : "======== Type reference directive '{0}' was not resolved. ========", - "Resolving_with_primary_search_path_0_6121" : "Resolving with primary search path '{0}'.", - "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122" : "Root directory cannot be determined, skipping primary search paths.", - "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123" : "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========", - "Type_declaration_files_to_be_included_in_compilation_6124" : "Type declaration files to be included in compilation.", - "Looking_up_in_node_modules_folder_initial_location_0_6125" : "Looking up in 'node_modules' folder, initial location '{0}'.", - "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126" : "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder.", - "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127" : "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========", - "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128" : "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========", - "Resolving_real_path_for_0_result_1_6130" : "Resolving real path for '{0}', result '{1}'.", - "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131" : "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'.", - "File_name_0_has_a_1_extension_stripping_it_6132" : "File name '{0}' has a '{1}' extension - stripping it.", - "_0_is_declared_but_its_value_is_never_read_6133" : "'{0}' is declared but its value is never read.", - "Report_errors_on_unused_locals_6134" : "Report errors on unused locals.", - "Report_errors_on_unused_parameters_6135" : "Report errors on unused parameters.", - "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136" : "The maximum dependency depth to search under node_modules and load JavaScript files.", - "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137" : "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'.", - "Property_0_is_declared_but_its_value_is_never_read_6138" : "Property '{0}' is declared but its value is never read.", - "Import_emit_helpers_from_tslib_6139" : "Import emit helpers from 'tslib'.", - "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140" : "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'.", - "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141" : "Parse in strict mode and emit \"use strict\" for each source file.", - "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142" : "Module '{0}' was resolved to '{1}', but '--jsx' is not set.", - "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144" : "Module '{0}' was resolved as locally declared ambient module in file '{1}'.", - "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145" : "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified.", - "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146" : "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'.", - "Resolution_for_module_0_was_found_in_cache_from_location_1_6147" : "Resolution for module '{0}' was found in cache from location '{1}'.", - "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148" : "Directory '{0}' does not exist, skipping all lookups in it.", - "Show_diagnostic_information_6149" : "Show diagnostic information.", - "Show_verbose_diagnostic_information_6150" : "Show verbose diagnostic information.", - "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151" : "Emit a single file with source maps instead of having a separate file.", - "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152" : "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.", - "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153" : "Transpile each file as a separate module (similar to 'ts.transpileModule').", - "Print_names_of_generated_files_part_of_the_compilation_6154" : "Print names of generated files part of the compilation.", - "Print_names_of_files_part_of_the_compilation_6155" : "Print names of files part of the compilation.", - "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156" : "The locale used when displaying messages to the user (e.g. 'en-us')", - "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157" : "Do not generate custom helper functions like '__extends' in compiled output.", - "Do_not_include_the_default_library_file_lib_d_ts_6158" : "Do not include the default library file (lib.d.ts).", - "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159" : "Do not add triple-slash references or imported modules to the list of compiled files.", - "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160" : "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.", - "List_of_folders_to_include_type_definitions_from_6161" : "List of folders to include type definitions from.", - "Disable_size_limitations_on_JavaScript_projects_6162" : "Disable size limitations on JavaScript projects.", - "The_character_set_of_the_input_files_6163" : "The character set of the input files.", - "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164" : "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.", - "Do_not_truncate_error_messages_6165" : "Do not truncate error messages.", - "Output_directory_for_generated_declaration_files_6166" : "Output directory for generated declaration files.", - "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167" : "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.", - "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168" : "List of root folders whose combined content represents the structure of the project at runtime.", - "Show_all_compiler_options_6169" : "Show all compiler options.", - "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170" : "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file", - "Command_line_Options_6171" : "Command-line Options", - "Basic_Options_6172" : "Basic Options", - "Strict_Type_Checking_Options_6173" : "Strict Type-Checking Options", - "Module_Resolution_Options_6174" : "Module Resolution Options", - "Source_Map_Options_6175" : "Source Map Options", - "Additional_Checks_6176" : "Additional Checks", - "Experimental_Options_6177" : "Experimental Options", - "Advanced_Options_6178" : "Advanced Options", - "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179" : "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'.", - "Enable_all_strict_type_checking_options_6180" : "Enable all strict type-checking options.", - "List_of_language_service_plugins_6181" : "List of language service plugins.", - "Scoped_package_detected_looking_in_0_6182" : "Scoped package detected, looking in '{0}'", - "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183" : "Reusing resolution of module '{0}' to file '{1}' from old program.", - "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184" : "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program.", - "Disable_strict_checking_of_generic_signatures_in_function_types_6185" : "Disable strict checking of generic signatures in function types.", - "Enable_strict_checking_of_function_types_6186" : "Enable strict checking of function types.", - "Enable_strict_checking_of_property_initialization_in_classes_6187" : "Enable strict checking of property initialization in classes.", - "Numeric_separators_are_not_allowed_here_6188" : "Numeric separators are not allowed here.", - "Multiple_consecutive_numeric_separators_are_not_permitted_6189" : "Multiple consecutive numeric separators are not permitted.", - "Found_package_json_at_0_Package_ID_is_1_6190" : "Found 'package.json' at '{0}'. Package ID is '{1}'.", - "Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191" : "Whether to keep outdated console output in watch mode instead of clearing the screen.", - "All_imports_in_import_declaration_are_unused_6192" : "All imports in import declaration are unused.", - "Found_1_error_Watching_for_file_changes_6193" : "Found 1 error. Watching for file changes.", - "Found_0_errors_Watching_for_file_changes_6194" : "Found {0} errors. Watching for file changes.", - "Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" : "Resolve 'keyof' to string valued property names only (no numbers or symbols).", - "_0_is_declared_but_never_used_6196" : "'{0}' is declared but never used.", - "Variable_0_implicitly_has_an_1_type_7005" : "Variable '{0}' implicitly has an '{1}' type.", - "Parameter_0_implicitly_has_an_1_type_7006" : "Parameter '{0}' implicitly has an '{1}' type.", - "Member_0_implicitly_has_an_1_type_7008" : "Member '{0}' implicitly has an '{1}' type.", - "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009" : "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.", - "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010" : "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type.", - "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011" : "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type.", - "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013" : "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.", - "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015" : "Element implicitly has an 'any' type because index expression is not of type 'number'.", - "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016" : "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.", - "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017" : "Element implicitly has an 'any' type because type '{0}' has no index signature.", - "Object_literal_s_property_0_implicitly_has_an_1_type_7018" : "Object literal's property '{0}' implicitly has an '{1}' type.", - "Rest_parameter_0_implicitly_has_an_any_type_7019" : "Rest parameter '{0}' implicitly has an 'any[]' type.", - "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" : "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.", - "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022" : "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.", - "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023" : "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.", - "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024" : "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.", - "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025" : "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type.", - "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026" : "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists.", - "Unreachable_code_detected_7027" : "Unreachable code detected.", - "Unused_label_7028" : "Unused label.", - "Fallthrough_case_in_switch_7029" : "Fallthrough case in switch.", - "Not_all_code_paths_return_a_value_7030" : "Not all code paths return a value.", - "Binding_element_0_implicitly_has_an_1_type_7031" : "Binding element '{0}' implicitly has an '{1}' type.", - "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032" : "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.", - "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033" : "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.", - "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034" : "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.", - "Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035" : "Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`", - "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" : "Dynamic import's specifier must be of type 'string', but here has type '{0}'.", - "Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037" : "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.", - "A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_7038" : "A namespace-style import cannot be called or constructed, and will cause a failure at runtime.", - "Mapped_object_type_implicitly_has_an_any_template_type_7039" : "Mapped object type implicitly has an 'any' template type.", - "You_cannot_rename_this_element_8000" : "You cannot rename this element.", - "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001" : "You cannot rename elements that are defined in the standard TypeScript library.", - "import_can_only_be_used_in_a_ts_file_8002" : "'import ... =' can only be used in a .ts file.", - "export_can_only_be_used_in_a_ts_file_8003" : "'export=' can only be used in a .ts file.", - "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004" : "'type parameter declarations' can only be used in a .ts file.", - "implements_clauses_can_only_be_used_in_a_ts_file_8005" : "'implements clauses' can only be used in a .ts file.", - "interface_declarations_can_only_be_used_in_a_ts_file_8006" : "'interface declarations' can only be used in a .ts file.", - "module_declarations_can_only_be_used_in_a_ts_file_8007" : "'module declarations' can only be used in a .ts file.", - "type_aliases_can_only_be_used_in_a_ts_file_8008" : "'type aliases' can only be used in a .ts file.", - "_0_can_only_be_used_in_a_ts_file_8009" : "'{0}' can only be used in a .ts file.", - "types_can_only_be_used_in_a_ts_file_8010" : "'types' can only be used in a .ts file.", - "type_arguments_can_only_be_used_in_a_ts_file_8011" : "'type arguments' can only be used in a .ts file.", - "parameter_modifiers_can_only_be_used_in_a_ts_file_8012" : "'parameter modifiers' can only be used in a .ts file.", - "non_null_assertions_can_only_be_used_in_a_ts_file_8013" : "'non-null assertions' can only be used in a .ts file.", - "enum_declarations_can_only_be_used_in_a_ts_file_8015" : "'enum declarations' can only be used in a .ts file.", - "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016" : "'type assertion expressions' can only be used in a .ts file.", - "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017" : "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.", - "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018" : "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.", - "Report_errors_in_js_files_8019" : "Report errors in .js files.", - "JSDoc_types_can_only_be_used_inside_documentation_comments_8020" : "JSDoc types can only be used inside documentation comments.", - "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021" : "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.", - "JSDoc_0_is_not_attached_to_a_class_8022" : "JSDoc '@{0}' is not attached to a class.", - "JSDoc_0_1_does_not_match_the_extends_2_clause_8023" : "JSDoc '@{0} {1}' does not match the 'extends {2}' clause.", - "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024" : "JSDoc '@param' tag has name '{0}', but there is no parameter with that name.", - "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" : "Class declarations cannot have more than one `@augments` or `@extends` tag.", - "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" : "Expected {0} type arguments; provide these with an '@extends' tag.", - "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" : "Expected {0}-{1} type arguments; provide these with an '@extends' tag.", - "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028" : "JSDoc '...' may only appear in the last parameter of a signature.", - "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029" : "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type.", - "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002" : "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.", - "class_expressions_are_not_currently_supported_9003" : "'class' expressions are not currently supported.", - "Language_service_is_disabled_9004" : "Language service is disabled.", - "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000" : "JSX attributes must only be assigned a non-empty 'expression'.", - "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001" : "JSX elements cannot have multiple attributes with the same name.", - "Expected_corresponding_JSX_closing_tag_for_0_17002" : "Expected corresponding JSX closing tag for '{0}'.", - "JSX_attribute_expected_17003" : "JSX attribute expected.", - "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004" : "Cannot use JSX unless the '--jsx' flag is provided.", - "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005" : "A constructor cannot contain a 'super' call when its class extends 'null'.", - "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006" : "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.", - "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007" : "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.", - "JSX_element_0_has_no_corresponding_closing_tag_17008" : "JSX element '{0}' has no corresponding closing tag.", - "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009" : "'super' must be called before accessing 'this' in the constructor of a derived class.", - "Unknown_type_acquisition_option_0_17010" : "Unknown type acquisition option '{0}'.", - "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011" : "'super' must be called before accessing a property of 'super' in the constructor of a derived class.", - "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" : "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?", - "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013" : "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor.", - "JSX_fragment_has_no_corresponding_closing_tag_17014" : "JSX fragment has no corresponding closing tag.", - "Expected_corresponding_closing_tag_for_JSX_fragment_17015" : "Expected corresponding closing tag for JSX fragment.", - "JSX_fragment_is_not_supported_when_using_jsxFactory_17016" : "JSX fragment is not supported when using --jsxFactory", - "JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma_17017" : "JSX fragment is not supported when using an inline JSX factory pragma", - "Circularity_detected_while_resolving_configuration_Colon_0_18000" : "Circularity detected while resolving configuration: {0}", - "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001" : "A path in an 'extends' option must be relative or rooted, but '{0}' is not.", - "The_files_list_in_config_file_0_is_empty_18002" : "The 'files' list in config file '{0}' is empty.", - "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003" : "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'.", - "File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module_80001" : "File is a CommonJS module; it may be converted to an ES6 module.", - "This_constructor_function_may_be_converted_to_a_class_declaration_80002" : "This constructor function may be converted to a class declaration.", - "Import_may_be_converted_to_a_default_import_80003" : "Import may be converted to a default import.", - "JSDoc_types_may_be_moved_to_TypeScript_types_80004" : "JSDoc types may be moved to TypeScript types.", - "require_call_may_be_converted_to_an_import_80005" : "'require' call may be converted to an import.", - "Add_missing_super_call_90001" : "Add missing 'super()' call", - "Make_super_call_the_first_statement_in_the_constructor_90002" : "Make 'super()' call the first statement in the constructor", - "Change_extends_to_implements_90003" : "Change 'extends' to 'implements'", - "Remove_declaration_for_Colon_0_90004" : "Remove declaration for: '{0}'", - "Remove_import_from_0_90005" : "Remove import from '{0}'", - "Implement_interface_0_90006" : "Implement interface '{0}'", - "Implement_inherited_abstract_class_90007" : "Implement inherited abstract class", - "Add_0_to_unresolved_variable_90008" : "Add '{0}.' to unresolved variable", - "Import_0_from_module_1_90013" : "Import '{0}' from module \"{1}\"", - "Change_0_to_1_90014" : "Change '{0}' to '{1}'", - "Add_0_to_existing_import_declaration_from_1_90015" : "Add '{0}' to existing import declaration from \"{1}\"", - "Declare_property_0_90016" : "Declare property '{0}'", - "Add_index_signature_for_property_0_90017" : "Add index signature for property '{0}'", - "Disable_checking_for_this_file_90018" : "Disable checking for this file", - "Ignore_this_error_message_90019" : "Ignore this error message", - "Initialize_property_0_in_the_constructor_90020" : "Initialize property '{0}' in the constructor", - "Initialize_static_property_0_90021" : "Initialize static property '{0}'", - "Change_spelling_to_0_90022" : "Change spelling to '{0}'", - "Declare_method_0_90023" : "Declare method '{0}'", - "Declare_static_method_0_90024" : "Declare static method '{0}'", - "Prefix_0_with_an_underscore_90025" : "Prefix '{0}' with an underscore", - "Rewrite_as_the_indexed_access_type_0_90026" : "Rewrite as the indexed access type '{0}'", - "Declare_static_property_0_90027" : "Declare static property '{0}'", - "Call_decorator_expression_90028" : "Call decorator expression", - "Add_async_modifier_to_containing_function_90029" : "Add async modifier to containing function", - "Convert_function_to_an_ES2015_class_95001" : "Convert function to an ES2015 class", - "Convert_function_0_to_class_95002" : "Convert function '{0}' to class", - "Extract_to_0_in_1_95004" : "Extract to {0} in {1}", - "Extract_function_95005" : "Extract function", - "Extract_constant_95006" : "Extract constant", - "Extract_to_0_in_enclosing_scope_95007" : "Extract to {0} in enclosing scope", - "Extract_to_0_in_1_scope_95008" : "Extract to {0} in {1} scope", - "Annotate_with_type_from_JSDoc_95009" : "Annotate with type from JSDoc", - "Annotate_with_types_from_JSDoc_95010" : "Annotate with types from JSDoc", - "Infer_type_of_0_from_usage_95011" : "Infer type of '{0}' from usage", - "Infer_parameter_types_from_usage_95012" : "Infer parameter types from usage", - "Convert_to_default_import_95013" : "Convert to default import", - "Install_0_95014" : "Install '{0}'", - "Replace_import_with_0_95015" : "Replace import with '{0}'.", - "Use_synthetic_default_member_95016" : "Use synthetic 'default' member.", - "Convert_to_ES6_module_95017" : "Convert to ES6 module", - "Add_undefined_type_to_property_0_95018" : "Add 'undefined' type to property '{0}'", - "Add_initializer_to_property_0_95019" : "Add initializer to property '{0}'", - "Add_definite_assignment_assertion_to_property_0_95020" : "Add definite assignment assertion to property '{0}'", - "Add_all_missing_members_95022" : "Add all missing members", - "Infer_all_types_from_usage_95023" : "Infer all types from usage", - "Delete_all_unused_declarations_95024" : "Delete all unused declarations", - "Prefix_all_unused_declarations_with_where_possible_95025" : "Prefix all unused declarations with '_' where possible", - "Fix_all_detected_spelling_errors_95026" : "Fix all detected spelling errors", - "Add_initializers_to_all_uninitialized_properties_95027" : "Add initializers to all uninitialized properties", - "Add_definite_assignment_assertions_to_all_uninitialized_properties_95028" : "Add definite assignment assertions to all uninitialized properties", - "Add_undefined_type_to_all_uninitialized_properties_95029" : "Add undefined type to all uninitialized properties", - "Change_all_jsdoc_style_types_to_TypeScript_95030" : "Change all jsdoc-style types to TypeScript", - "Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types_95031" : "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)", - "Implement_all_unimplemented_interfaces_95032" : "Implement all unimplemented interfaces", - "Install_all_missing_types_packages_95033" : "Install all missing types packages", - "Rewrite_all_as_indexed_access_types_95034" : "Rewrite all as indexed access types", - "Convert_all_to_default_imports_95035" : "Convert all to default imports", - "Make_all_super_calls_the_first_statement_in_their_constructor_95036" : "Make all 'super()' calls the first statement in their constructor", - "Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" : "Add qualifier to all unresolved variables matching a member name", - "Change_all_extended_interfaces_to_implements_95038" : "Change all extended interfaces to 'implements'", - "Add_all_missing_super_calls_95039" : "Add all missing super calls", - "Implement_all_inherited_abstract_classes_95040" : "Implement all inherited abstract classes", - "Add_all_missing_async_modifiers_95041" : "Add all missing 'async' modifiers", - "Add_ts_ignore_to_all_error_messages_95042" : "Add '@ts-ignore' to all error messages", - "Annotate_everything_with_types_from_JSDoc_95043" : "Annotate everything with types from JSDoc", - "Add_to_all_uncalled_decorators_95044" : "Add '()' to all uncalled decorators", - "Convert_all_constructor_functions_to_classes_95045" : "Convert all constructor functions to classes", - "Generate_get_and_set_accessors_95046" : "Generate 'get' and 'set' accessors", - "Convert_require_to_import_95047" : "Convert 'require' to 'import'", - "Convert_all_require_to_import_95048" : "Convert all 'require' to 'import'" -} \ No newline at end of file diff --git a/lib/lib.esnext.array.d.ts b/lib/lib.esnext.array.d.ts deleted file mode 100644 index 6c75122320954..0000000000000 --- a/lib/lib.esnext.array.d.ts +++ /dev/null @@ -1,223 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - - - -/// - - -interface ReadonlyArray { - - /** - * Calls a defined callback function on each element of an array. Then, flattens the result into - * a new array. - * This is identical to a map followed by flat with depth 1. - * - * @param callback A function that accepts up to three arguments. The flatMap method calls the - * callback function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callback function. If - * thisArg is omitted, undefined is used as the this value. - */ - flatMap ( - callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray, - thisArg?: This - ): U[] - - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: - ReadonlyArray | - - ReadonlyArray> | - ReadonlyArray[]> | - ReadonlyArray[][]> | - ReadonlyArray[][][]> | - - ReadonlyArray>> | - ReadonlyArray[][]>> | - ReadonlyArray>[][]> | - ReadonlyArray[]>[]> | - ReadonlyArray>[]> | - ReadonlyArray[]>> | - - ReadonlyArray>>> | - ReadonlyArray[]>>> | - ReadonlyArray>[]>> | - ReadonlyArray>>[]> | - - ReadonlyArray>>>>, - depth: 4): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: - ReadonlyArray | - - ReadonlyArray[][]> | - ReadonlyArray[]> | - ReadonlyArray> | - - ReadonlyArray>> | - ReadonlyArray[]>> | - ReadonlyArray>[]> | - - ReadonlyArray>>>, - depth: 3): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: - ReadonlyArray | - - ReadonlyArray> | - ReadonlyArray[]> | - - ReadonlyArray>>, - depth: 2): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: - ReadonlyArray | - ReadonlyArray>, - depth?: 1 - ): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: - ReadonlyArray, - depth: 0 - ): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. If no depth is provided, flat method defaults to the depth of 1. - * - * @param depth The maximum recursion depth - */ - flat(depth?: number): any[]; - } - -interface Array { - - /** - * Calls a defined callback function on each element of an array. Then, flattens the result into - * a new array. - * This is identical to a map followed by flat with depth 1. - * - * @param callback A function that accepts up to three arguments. The flatMap method calls the - * callback function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callback function. If - * thisArg is omitted, undefined is used as the this value. - */ - flatMap ( - callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray, - thisArg?: This - ): U[] - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][][][][][][], depth: 7): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][][][][][], depth: 6): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][][][][], depth: 5): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][][][], depth: 4): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][][], depth: 3): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][][], depth: 2): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[][], depth?: 1): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. - * - * @param depth The maximum recursion depth - */ - flat(this: U[], depth: 0): U[]; - - /** - * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. If no depth is provided, flat method defaults to the depth of 1. - * - * @param depth The maximum recursion depth - */ - flat(depth?: number): any[]; -} diff --git a/lib/lib.esnext.asynciterable.d.ts b/lib/lib.esnext.asynciterable.d.ts deleted file mode 100644 index 38e12a7caf638..0000000000000 --- a/lib/lib.esnext.asynciterable.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - - - -/// - - -/// -/// - -interface SymbolConstructor { - /** - * A method that returns the default async iterator for an object. Called by the semantics of - * the for-await-of statement. - */ - readonly asyncIterator: symbol; -} - -interface AsyncIterator { - next(value?: any): Promise>; - return?(value?: any): Promise>; - throw?(e?: any): Promise>; -} - -interface AsyncIterable { - [Symbol.asyncIterator](): AsyncIterator; -} - -interface AsyncIterableIterator extends AsyncIterator { - [Symbol.asyncIterator](): AsyncIterableIterator; -} \ No newline at end of file diff --git a/lib/lib.esnext.bigint.d.ts b/lib/lib.esnext.bigint.d.ts deleted file mode 100644 index 50967de98fea7..0000000000000 --- a/lib/lib.esnext.bigint.d.ts +++ /dev/null @@ -1,629 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - - - -/// - - -interface BigInt { - /** - * Returns a string representation of an object. - * @param radix Specifies a radix for converting numeric values to strings. - */ - toString(radix?: number): string; - - /** Returns a string representation appropriate to the host environment's current locale. */ - toLocaleString(): string; - - /** Returns the primitive value of the specified object. */ - valueOf(): bigint; - - readonly [Symbol.toStringTag]: "BigInt"; -} - -interface BigIntConstructor { - (value?: any): bigint; - readonly prototype: BigInt; - - /** - * Interprets the low bits of a BigInt as a 2's-complement signed integer. - * All higher bits are discarded. - * @param bits The number of low bits to use - * @param int The BigInt whose bits to extract - */ - asIntN(bits: number, int: bigint): bigint; - /** - * Interprets the low bits of a BigInt as an unsigned integer. - * All higher bits are discarded. - * @param bits The number of low bits to use - * @param int The BigInt whose bits to extract - */ - asUintN(bits: number, int: bigint): bigint; -} - -declare var BigInt: BigIntConstructor; - -/** - * A typed array of 64-bit signed integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated, an exception is raised. - */ -interface BigInt64Array { - /** The size in bytes of each element in the array. */ - readonly BYTES_PER_ELEMENT: number; - - /** The ArrayBuffer instance referenced by the array. */ - readonly buffer: ArrayBufferLike; - - /** The length in bytes of the array. */ - readonly byteLength: number; - - /** The offset in bytes of the array. */ - readonly byteOffset: number; - - /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ - copyWithin(target: number, start: number, end?: number): this; - - /** Yields index, value pairs for every entry in the array. */ - entries(): IterableIterator<[number, bigint]>; - - /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in the array until the callbackfn returns false, - * or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - every(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean; - - /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ - fill(value: bigint, start?: number, end?: number): this; - - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - filter(callbackfn: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array; - - /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined; - - /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number; - - /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void; - - /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ - includes(searchElement: bigint, fromIndex?: number): boolean; - - /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - indexOf(searchElement: bigint, fromIndex?: number): number; - - /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the - * resulting String. If omitted, the array elements are separated with a comma. - */ - join(separator?: string): string; - - /** Yields each index in the array. */ - keys(): IterableIterator; - - /** - * Returns the index of the last occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - lastIndexOf(searchElement: bigint, fromIndex?: number): number; - - /** The length of the array. */ - readonly length: number; - - /** - * Calls a defined callback function on each element of an array, and returns an array that - * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array; - - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint; - - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U; - - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ - reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint; - - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduceRight(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U; - - /** Reverses the elements in the array. */ - reverse(): this; - - /** - * Sets a value or an array of values. - * @param array A typed or untyped array of values to set. - * @param offset The index in the current array at which the values are to be written. - */ - set(array: ArrayLike, offset?: number): void; - - /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. - */ - slice(start?: number, end?: number): BigInt64Array; - - /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in the array until the callbackfn returns true, or until - * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - some(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean; - - /** - * Sorts the array. - * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. - */ - sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this; - - /** - * Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. - * @param begin The index of the beginning of the array. - * @param end The index of the end of the array. - */ - subarray(begin: number, end?: number): BigInt64Array; - - /** Converts the array to a string by using the current locale. */ - toLocaleString(): string; - - /** Returns a string representation of the array. */ - toString(): string; - - /** Yields each value in the array. */ - values(): IterableIterator; - - [Symbol.iterator](): IterableIterator; - - readonly [Symbol.toStringTag]: "BigInt64Array"; - - [index: number]: bigint; -} - -interface BigInt64ArrayConstructor { - readonly prototype: BigInt64Array; - new(length?: number): BigInt64Array; - new(array: Iterable): BigInt64Array; - new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array; - - /** The size in bytes of each element in the array. */ - readonly BYTES_PER_ELEMENT: number; - - /** - * Returns a new array from a set of elements. - * @param items A set of elements to include in the new array object. - */ - of(...items: bigint[]): BigInt64Array; - - /** - * Creates an array from an array-like or iterable object. - * @param arrayLike An array-like or iterable object to convert to an array. - * @param mapfn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - from(arrayLike: ArrayLike): BigInt64Array; - from(arrayLike: ArrayLike, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array; -} - -declare var BigInt64Array: BigInt64ArrayConstructor; - -/** - * A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated, an exception is raised. - */ -interface BigUint64Array { - /** The size in bytes of each element in the array. */ - readonly BYTES_PER_ELEMENT: number; - - /** The ArrayBuffer instance referenced by the array. */ - readonly buffer: ArrayBufferLike; - - /** The length in bytes of the array. */ - readonly byteLength: number; - - /** The offset in bytes of the array. */ - readonly byteOffset: number; - - /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ - copyWithin(target: number, start: number, end?: number): this; - - /** Yields index, value pairs for every entry in the array. */ - entries(): IterableIterator<[number, bigint]>; - - /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in the array until the callbackfn returns false, - * or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - every(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean; - - /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ - fill(value: bigint, start?: number, end?: number): this; - - /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - filter(callbackfn: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array; - - /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined; - - /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ - findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number; - - /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void; - - /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ - includes(searchElement: bigint, fromIndex?: number): boolean; - - /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - indexOf(searchElement: bigint, fromIndex?: number): number; - - /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the - * resulting String. If omitted, the array elements are separated with a comma. - */ - join(separator?: string): string; - - /** Yields each index in the array. */ - keys(): IterableIterator; - - /** - * Returns the index of the last occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ - lastIndexOf(searchElement: bigint, fromIndex?: number): number; - - /** The length of the array. */ - readonly length: number; - - /** - * Calls a defined callback function on each element of an array, and returns an array that - * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array; - - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint; - - /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduce(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U; - - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ - reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint; - - /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ - reduceRight(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U; - - /** Reverses the elements in the array. */ - reverse(): this; - - /** - * Sets a value or an array of values. - * @param array A typed or untyped array of values to set. - * @param offset The index in the current array at which the values are to be written. - */ - set(array: ArrayLike, offset?: number): void; - - /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. - */ - slice(start?: number, end?: number): BigUint64Array; - - /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in the array until the callbackfn returns true, or until - * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ - some(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean; - - /** - * Sorts the array. - * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. - */ - sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this; - - /** - * Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. - * @param begin The index of the beginning of the array. - * @param end The index of the end of the array. - */ - subarray(begin: number, end?: number): BigUint64Array; - - /** Converts the array to a string by using the current locale. */ - toLocaleString(): string; - - /** Returns a string representation of the array. */ - toString(): string; - - /** Yields each value in the array. */ - values(): IterableIterator; - - [Symbol.iterator](): IterableIterator; - - readonly [Symbol.toStringTag]: "BigUint64Array"; - - [index: number]: bigint; -} - -interface BigUint64ArrayConstructor { - readonly prototype: BigUint64Array; - new(length?: number): BigUint64Array; - new(array: Iterable): BigUint64Array; - new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array; - - /** The size in bytes of each element in the array. */ - readonly BYTES_PER_ELEMENT: number; - - /** - * Returns a new array from a set of elements. - * @param items A set of elements to include in the new array object. - */ - of(...items: bigint[]): BigUint64Array; - - /** - * Creates an array from an array-like or iterable object. - * @param arrayLike An array-like or iterable object to convert to an array. - * @param mapfn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ - from(arrayLike: ArrayLike): BigUint64Array; - from(arrayLike: ArrayLike, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array; -} - -declare var BigUint64Array: BigUint64ArrayConstructor; - -interface DataView { - /** - * Gets the BigInt64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getBigInt64(byteOffset: number, littleEndian?: boolean): bigint; - - /** - * Gets the BigUint64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ - getBigUint64(byteOffset: number, littleEndian?: boolean): bigint; - - /** - * Stores a BigInt64 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void; - - /** - * Stores a BigUint64 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ - setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void; -} diff --git a/lib/lib.esnext.symbol.d.ts b/lib/lib.esnext.symbol.d.ts deleted file mode 100644 index 98293eaf5721a..0000000000000 --- a/lib/lib.esnext.symbol.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - - - -/// - - -interface Symbol { - /** - * expose the [[Description]] internal slot of a symbol directly - */ - readonly description: string; -} diff --git a/package.json b/package.json index 6947d7ec11f92..7f9e66add40e7 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@types/through2": "latest", "@types/travis-fold": "latest", "@types/xml2js": "^0.4.0", - "@typescript-eslint/eslint-plugin": "^3.4.1-alpha.1", + "@typescript-eslint/eslint-plugin": "^3.6.1-alpha.1", "@typescript-eslint/experimental-utils": "^3.4.1-alpha.1", "@typescript-eslint/parser": "^3.4.1-alpha.1", "async": "latest", diff --git a/scripts/createPlaygroundBuild.js b/scripts/createPlaygroundBuild.js new file mode 100644 index 0000000000000..8fbee8ce8a676 --- /dev/null +++ b/scripts/createPlaygroundBuild.js @@ -0,0 +1,322 @@ +// @ts-check + +// This script does two things: +// +// - Listens to changes to the built version of TypeScript (via a filewatcher on `built/local/typescriptServices.js`) +// these trigger creating monaco-typescript compatible builds of TypeScript at `internal/lib/typescriptServices.js§ +// +// - Creates a HTTP server which the playground uses. The webserver almost exclusively re-directs requests to +// the latest stable version of monaco-typescript, but specifically overrides requests for the TypeScript js +// file to the version created in the above step. +// + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const path = require('path'); +const fs = require('fs'); +const child_process = require('child_process'); +const http = require('http'); +const url = require('url'); + +function updateTSDist() { + // This code is a direct port of a script from monaco-typescript + // https://github.com/microsoft/monaco-typescript/blob/master/scripts/importTypescript.js + // Currently based on 778ace1 on Apr 25 2020 + + const generatedNote = `// + // **NOTE**: Do not edit directly! This file is generated using \`npm run import-typescript\` + // + `; + + const TYPESCRIPT_LIB_SOURCE = path.join(__dirname, '../built/local'); + const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../internal/lib'); + + (function () { + try { + fs.statSync(TYPESCRIPT_LIB_DESTINATION); + } catch (err) { + fs.mkdirSync(TYPESCRIPT_LIB_DESTINATION); + } + importLibs(); + + const npmLsOutput = JSON.parse(child_process.execSync("npm ls typescript --depth=0 --json=true").toString()); + const typeScriptDependencyVersion = npmLsOutput.dependencies.typescript.version; + + fs.writeFileSync( + path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServicesMetadata.ts'), + `${generatedNote} + export const typescriptVersion = "${typeScriptDependencyVersion}";\n` + ); + + var tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.js')).toString(); + + // Ensure we never run into the node system... + // (this also removes require calls that trick webpack into shimming those modules...) + tsServices = ( + tsServices.replace(/\n ts\.sys =([^]*)\n \}\)\(\);/m, `\n // MONACOCHANGE\n ts.sys = undefined;\n // END MONACOCHANGE`) + ); + + // Eliminate more require() calls... + tsServices = tsServices.replace(/^( +)etwModule = require\(.*$/m, '$1// MONACOCHANGE\n$1etwModule = undefined;\n$1// END MONACOCHANGE'); + tsServices = tsServices.replace(/^( +)var result = ts\.sys\.require\(.*$/m, '$1// MONACOCHANGE\n$1var result = undefined;\n$1// END MONACOCHANGE'); + + // Flag any new require calls (outside comments) so they can be corrected preemptively. + // To avoid missing cases (or using an even more complex regex), temporarily remove comments + // about require() and then check for lines actually calling require(). + // \/[*/] matches the start of a comment (single or multi-line). + // ^\s+\*[^/] matches (presumably) a later line of a multi-line comment. + const tsServicesNoCommentedRequire = tsServices.replace(/(\/[*/]|^\s+\*[^/]).*\brequire\(.*/gm, ''); + const linesWithRequire = tsServicesNoCommentedRequire.match(/^.*?\brequire\(.*$/gm) + + // Allow error messages to include references to require() in their strings + const runtimeRequires = linesWithRequire && linesWithRequire.filter(l => !l.includes(": diag(")) + + if (runtimeRequires && runtimeRequires.length) { + console.error('Found new require() calls on the following lines. These should be removed to avoid breaking webpack builds.\n'); + console.error(linesWithRequire.join('\n')); + process.exit(1); + } + + // Make sure process.args don't get called in the browser, this + // should only happen in TS 2.6.2 + const beforeProcess = `ts.perfLogger.logInfoEvent("Starting TypeScript v" + ts.versionMajorMinor + " with command line: " + JSON.stringify(process.argv));` + const afterProcess = `// MONACOCHANGE\n ts.perfLogger.logInfoEvent("Starting TypeScript v" + ts.versionMajorMinor + " with command line: " + JSON.stringify([]));\n// END MONACOCHANGE` + tsServices = tsServices.replace(beforeProcess, afterProcess); + + var tsServices_amd = generatedNote + tsServices + + ` + // MONACOCHANGE + // Defining the entire module name because r.js has an issue and cannot bundle this file + // correctly with an anonymous define call + define("vs/language/typescript/lib/typescriptServices", [], function() { return ts; }); + // END MONACOCHANGE + `; + fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices-amd.js'), tsServices_amd); + + var tsServices_esm = generatedNote + tsServices + + ` + // MONACOCHANGE + export var createClassifier = ts.createClassifier; + export var createLanguageService = ts.createLanguageService; + export var displayPartsToString = ts.displayPartsToString; + export var EndOfLineState = ts.EndOfLineState; + export var flattenDiagnosticMessageText = ts.flattenDiagnosticMessageText; + export var IndentStyle = ts.IndentStyle; + export var ScriptKind = ts.ScriptKind; + export var ScriptTarget = ts.ScriptTarget; + export var TokenClass = ts.TokenClass; + // END MONACOCHANGE + `; + fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.js'), tsServices_esm); + + var dtsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.d.ts')).toString(); + dtsServices += + ` + // MONACOCHANGE + export = ts; + // END MONACOCHANGE + `; + fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.d.ts'), generatedNote + dtsServices); + + })(); + + function importLibs() { + function getFileName(name) { + return (name === '' ? 'lib.d.ts' : `lib.${name}.d.ts`); + } + function getVariableName(name) { + return (name === '' ? 'lib_dts' : `lib_${name.replace(/\./g, '_')}_dts`); + } + function readLibFile(name) { + var srcPath = path.join(TYPESCRIPT_LIB_SOURCE, getFileName(name)); + return fs.readFileSync(srcPath).toString(); + } + + var queue = []; + var in_queue = {}; + + var enqueue = function (name) { + if (in_queue[name]) { + return; + } + in_queue[name] = true; + queue.push(name); + }; + + enqueue(''); + enqueue('es2015'); + + var result = []; + while (queue.length > 0) { + var name = queue.shift(); + var contents = readLibFile(name); + var lines = contents.split(/\r\n|\r|\n/); + + var output = ''; + var writeOutput = function (text) { + if (output.length === 0) { + output = text; + } else { + output += ` + ${text}`; + } + }; + var outputLines = []; + var flushOutputLines = function () { + writeOutput(`"${escapeText(outputLines.join('\n'))}"`); + outputLines = []; + }; + var deps = []; + for (let i = 0; i < lines.length; i++) { + let m = lines[i].match(/\/\/\/\s* 0) { + for (let i = result.length - 1; i >= 0; i--) { + if (result[i].deps.length === 0) { + // emit this node + strResult += `\nexport const ${result[i].name}: string = ${result[i].output};\n`; + + // mark dep as resolved + for (let j = 0; j < result.length; j++) { + for (let k = 0; k < result[j].deps.length; k++) { + if (result[j].deps[k] === result[i].name) { + result[j].deps.splice(k, 1); + break; + } + } + } + + // remove from result + result.splice(i, 1); + break; + } + } + } + + strResult += ` + /** This is the DTS which is used when the target is ES6 or below */ + export const lib_es5_bundled_dts = lib_dts; + + /** This is the DTS which is used by default in monaco-typescript, and when the target is 2015 or above */ + export const lib_es2015_bundled_dts = lib_es2015_dts + "" + lib_dom_dts + "" + lib_webworker_importscripts_dts + "" + lib_scripthost_dts + ""; + ` + + var dstPath = path.join(TYPESCRIPT_LIB_DESTINATION, 'lib.ts'); + fs.writeFileSync(dstPath, strResult); + } + + /** + * Escape text such that it can be used in a javascript string enclosed by double quotes (") + */ + function escapeText(text) { + // See http://www.javascriptkit.com/jsref/escapesequence.shtml + var _backspace = '\b'.charCodeAt(0); + var _formFeed = '\f'.charCodeAt(0); + var _newLine = '\n'.charCodeAt(0); + var _nullChar = 0; + var _carriageReturn = '\r'.charCodeAt(0); + var _tab = '\t'.charCodeAt(0); + var _verticalTab = '\v'.charCodeAt(0); + var _backslash = '\\'.charCodeAt(0); + var _doubleQuote = '"'.charCodeAt(0); + + var startPos = 0, chrCode, replaceWith = null, resultPieces = []; + + for (var i = 0, len = text.length; i < len; i++) { + chrCode = text.charCodeAt(i); + switch (chrCode) { + case _backspace: + replaceWith = '\\b'; + break; + case _formFeed: + replaceWith = '\\f'; + break; + case _newLine: + replaceWith = '\\n'; + break; + case _nullChar: + replaceWith = '\\0'; + break; + case _carriageReturn: + replaceWith = '\\r'; + break; + case _tab: + replaceWith = '\\t'; + break; + case _verticalTab: + replaceWith = '\\v'; + break; + case _backslash: + replaceWith = '\\\\'; + break; + case _doubleQuote: + replaceWith = '\\"'; + break; + } + if (replaceWith !== null) { + resultPieces.push(text.substring(startPos, i)); + resultPieces.push(replaceWith); + startPos = i + 1; + replaceWith = null; + } + } + resultPieces.push(text.substring(startPos, len)); + return resultPieces.join(''); + } + + /// End of import +} + +const services = path.join(__dirname, '../built/local/typescriptServices.js'); +fs.watchFile(services, () =>{ + console.log("Updating the monaco build") + updateTSDist() +}) + +http.createServer(function (req, res) { + const incoming = url.parse(req.url) + if (incoming.path.endsWith("typescriptServices.js")) { + // Use the built version + res.writeHead(200, {"Content-Type": "text/javascript"}); + const amdPath = path.join(__dirname, '../internal/lib/typescriptServices-amd.js'); + res.write(fs.readFileSync(amdPath)) + } else { + // Redirect to the TS CDN + res.writeHead(302, { + 'Location': `https://typescript.azureedge.net/cdn/3.9.2/monaco/${incoming.path}` + }); + } + + res.end(); +}).listen(5615); + +console.log("Starting servers\n") +console.log(" - [✓] file watcher: " + services) +console.log(" - [✓] http server: http://localhost:5615") + +console.log("\n\nGet started: http://www.staging-typescript.org/play?ts=dev") diff --git a/scripts/open-user-pr.ts b/scripts/open-user-pr.ts index 04cace3e698d8..49fda38a4f6f3 100644 --- a/scripts/open-user-pr.ts +++ b/scripts/open-user-pr.ts @@ -2,14 +2,14 @@ /// // Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally import { Octokit } from "@octokit/rest"; -import {runSequence} from "./run-sequence"; +const {runSequence} = require("./run-sequence"); -const userName = process.env.GH_USERNAME; +const userName = process.env.GH_USERNAME || "typescript-bot"; const reviewers = process.env.REQUESTING_USER ? [process.env.REQUESTING_USER] : ["weswigham", "sandersn", "RyanCavanaugh"]; const now = new Date(); const masterBranchname = `user-baseline-updates`; const targetBranch = process.env.TARGET_BRANCH || "master"; -const branchName = process.env.TARGET_FORK.toLowerCase() === "microsoft" && (targetBranch === "master" || targetBranch === "refs/heads/master") +const branchName = process.env.TARGET_FORK?.toLowerCase() === "microsoft" && (targetBranch === "master" || targetBranch === "refs/heads/master") ? masterBranchname : `user-update-${process.env.TARGET_FORK}-${process.env.TARGET_BRANCH ? "-" + process.env.TARGET_BRANCH : ""}`; const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`; @@ -46,7 +46,7 @@ cc ${reviewers.map(r => "@" + r).join(" ")}`, const num = r.data.number; console.log(`Pull request ${num} created.`); if (!process.env.SOURCE_ISSUE) { - await gh.pulls.createReviewRequest({ + await gh.pulls.requestReviewers({ owner: prOwner, repo: "TypeScript", pull_number: num, diff --git a/scripts/post-vsts-artifact-comment.js b/scripts/post-vsts-artifact-comment.js index 076d5a753067d..125b047f51901 100644 --- a/scripts/post-vsts-artifact-comment.js +++ b/scripts/post-vsts-artifact-comment.js @@ -47,8 +47,8 @@ and then running \`npm install\`. }); // Temporarily disable until we get access controls set up right - // Send a ping to https://github.com/orta/make-monaco-builds#pull-request-builds - await gh.request("POST /repos/orta/make-monaco-builds/dispatches", { event_type: process.env.SOURCE_ISSUE, headers: { Accept: "application/vnd.github.everest-preview+json" }}); + // Send a ping to https://github.com/microsoft/typescript-make-monaco-builds#pull-request-builds + await gh.request("POST /repos/microsoft/typescript-make-monaco-builds/dispatches", { event_type: process.env.SOURCE_ISSUE, headers: { Accept: "application/vnd.github.everest-preview+json" }}); } main().catch(async e => { diff --git a/scripts/produceLKG.ts b/scripts/produceLKG.ts index 762290bcfa6a0..7439abe9fcedf 100644 --- a/scripts/produceLKG.ts +++ b/scripts/produceLKG.ts @@ -3,7 +3,6 @@ import childProcess = require("child_process"); import fs = require("fs-extra"); import path = require("path"); -import removeInternal = require("remove-internal"); import glob = require("glob"); const root = path.join(__dirname, ".."); @@ -15,6 +14,7 @@ async function produceLKG() { console.log(`Building LKG from ${source} to ${dest}`); await copyLibFiles(); await copyLocalizedDiagnostics(); + await copyTypesMap(); await buildProtocol(); await copyScriptOutputs(); await copyDeclarationOutputs(); @@ -40,6 +40,10 @@ async function copyLocalizedDiagnostics() { } } +async function copyTypesMap() { + await copyFromBuiltLocal("typesMap.json"); // Cannot accommodate copyright header +} + async function buildProtocol() { const protocolScript = path.join(__dirname, "buildProtocol.js"); if (!fs.existsSync(protocolScript)) { diff --git a/src/compat/deprecations.ts b/src/compat/deprecations.ts index e9a6dc3b9a878..ed1034b7e6a1b 100644 --- a/src/compat/deprecations.ts +++ b/src/compat/deprecations.ts @@ -1321,4 +1321,24 @@ namespace ts { }); // #endregion Renamed node Tests + + // DEPRECATION: Renamed `Map` and `ReadonlyMap` interfaces + // DEPRECATION PLAN: + // - soft: 4.0 + // - remove: TBD (will remove for at least one release before replacing with `ESMap`/`ReadonlyESMap`) + // - replace: TBD (will eventually replace with `ESMap`/`ReadonlyESMap`) + // #region Renamed `Map` and `ReadonlyMap` interfaces + + /** + * @deprecated Use `ts.ReadonlyESMap` instead. + */ + export interface ReadonlyMap extends ReadonlyESMap { + } + + /** + * @deprecated Use `ts.ESMap` instead. + */ + export interface Map extends ESMap { } + + // #endregion } \ No newline at end of file diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ca3399375a28a..f61aa3ab900eb 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -15,7 +15,7 @@ namespace ts { referenced: boolean; } - export function getModuleInstanceState(node: ModuleDeclaration, visited?: Map): ModuleInstanceState { + export function getModuleInstanceState(node: ModuleDeclaration, visited?: ESMap): ModuleInstanceState { if (node.body && !node.body.parent) { // getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already setParent(node.body, node); @@ -35,7 +35,7 @@ namespace ts { return result; } - function getModuleInstanceStateWorker(node: Node, visited: Map): ModuleInstanceState { + function getModuleInstanceStateWorker(node: Node, visited: ESMap): ModuleInstanceState { // A module is uninstantiated if it contains only switch (node.kind) { // 1. interface declarations, type alias declarations @@ -107,7 +107,7 @@ namespace ts { return ModuleInstanceState.Instantiated; } - function getModuleInstanceStateForAliasTarget(specifier: ExportSpecifier, visited: Map) { + function getModuleInstanceStateForAliasTarget(specifier: ExportSpecifier, visited: ESMap) { const name = specifier.propertyName || specifier.name; let p: Node | undefined = specifier.parent; while (p) { @@ -218,7 +218,7 @@ namespace ts { let symbolCount = 0; let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; - let classifiableNames: UnderscoreEscapedMap; + let classifiableNames: Set<__String>; const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; @@ -237,7 +237,7 @@ namespace ts { options = opts; languageVersion = getEmitScriptTarget(options); inStrictMode = bindInStrictMode(file, opts); - classifiableNames = createUnderscoreEscapedMap(); + classifiableNames = new Set(); symbolCount = 0; Symbol = objectAllocator.getSymbolConstructor(); @@ -445,7 +445,7 @@ namespace ts { symbol = symbolTable.get(name); if (includes & SymbolFlags.Classifiable) { - classifiableNames.set(name, true); + classifiableNames.add(name); } if (!symbol) { @@ -537,10 +537,6 @@ namespace ts { symbol.parent = parent; } - if (node.flags & NodeFlags.Deprecated) { - symbol.flags |= SymbolFlags.Deprecated; - } - return symbol; } @@ -1245,6 +1241,11 @@ namespace ts { if (currentReturnTarget && returnLabel.antecedents) { addAntecedent(currentReturnTarget, createReduceLabel(finallyLabel, returnLabel.antecedents, currentFlow)); } + // If we have an outer exception target (i.e. a containing try-finally or try-catch-finally), add a + // control flow that goes back through the finally blok and back through each possible exception source. + if (currentExceptionTarget && exceptionLabel.antecedents) { + addAntecedent(currentExceptionTarget, createReduceLabel(finallyLabel, exceptionLabel.antecedents, currentFlow)); + } // If the end of the finally block is reachable, but the end of the try and catch blocks are not, // convert the current flow to unreachable. For example, 'try { return 1; } finally { ... }' should // result in an unreachable current control flow. @@ -1964,7 +1965,7 @@ namespace ts { } if (inStrictMode && !isAssignmentTarget(node)) { - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, ElementKind>(); for (const prop of node.properties) { if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) { @@ -2979,6 +2980,9 @@ namespace ts { } function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: BindableStaticNameExpression, isToplevel: boolean, isPrototypeProperty: boolean, containerIsClass: boolean) { + if (namespaceSymbol?.flags! & SymbolFlags.Alias) { + return namespaceSymbol; + } if (isToplevel && !isPrototypeProperty) { // make symbols or add declarations for intermediate containers const flags = SymbolFlags.Module | SymbolFlags.Assignment; @@ -3142,7 +3146,7 @@ namespace ts { bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName); // Add name of class expression into the map for semantic classifier if (node.name) { - classifiableNames.set(node.name.escapedText, true); + classifiableNames.add(node.name.escapedText); } } diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index ea92c99c5172f..7765a75331281 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -24,7 +24,7 @@ namespace ts { /** * Cache of bind and check diagnostics for files with their Path being the key */ - semanticDiagnosticsPerFile?: ReadonlyMap | undefined; + semanticDiagnosticsPerFile?: ReadonlyESMap | undefined; /** * The map has key by source file's path that has been changed */ @@ -41,7 +41,7 @@ namespace ts { * Map of file signatures, with key being file path, calculated while getting current changed file's affected files * These will be committed whenever the iteration through affected files of current changed file is complete */ - currentAffectedFilesSignatures?: ReadonlyMap | undefined; + currentAffectedFilesSignatures?: ReadonlyESMap | undefined; /** * Newly computed visible to outside referencedSet */ @@ -65,7 +65,7 @@ namespace ts { /** * Files pending to be emitted kind. */ - affectedFilesPendingEmitKind?: ReadonlyMap | undefined; + affectedFilesPendingEmitKind?: ReadonlyESMap | undefined; /** * Current index to retrieve pending affected file */ @@ -89,7 +89,7 @@ namespace ts { /** * Cache of bind and check diagnostics for files with their Path being the key */ - semanticDiagnosticsPerFile: Map | undefined; + semanticDiagnosticsPerFile: ESMap | undefined; /** * The map has key by source file's path that has been changed */ @@ -110,7 +110,7 @@ namespace ts { * Map of file signatures, with key being file path, calculated while getting current changed file's affected files * These will be committed whenever the iteration through affected files of current changed file is complete */ - currentAffectedFilesSignatures: Map | undefined; + currentAffectedFilesSignatures: ESMap | undefined; /** * Newly computed visible to outside referencedSet */ @@ -142,7 +142,7 @@ namespace ts { /** * Files pending to be emitted kind. */ - affectedFilesPendingEmitKind: Map | undefined; + affectedFilesPendingEmitKind: ESMap | undefined; /** * Current index to retrieve pending affected file */ @@ -154,7 +154,7 @@ namespace ts { /** * Already seen emitted files */ - seenEmittedFiles: Map | undefined; + seenEmittedFiles: ESMap | undefined; /** * true if program has been emitted */ @@ -1140,7 +1140,7 @@ namespace ts { } } - function getMapOfReferencedSet(mapLike: MapLike | undefined, toPath: (path: string) => Path): ReadonlyMap | undefined { + function getMapOfReferencedSet(mapLike: MapLike | undefined, toPath: (path: string) => Path): ReadonlyESMap | undefined { if (!mapLike) return undefined; const map = new Map(); // Copies keys/values from template. Note that for..in will not throw if diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 311f92ceabe12..1c26513897aee 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -15,36 +15,36 @@ namespace ts { /** * Information of the file eg. its version, signature etc */ - fileInfos: ReadonlyMap; + fileInfos: ReadonlyESMap; /** * Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled * Otherwise undefined * Thus non undefined value indicates, module emit */ - readonly referencedMap?: ReadonlyMap | undefined; + readonly referencedMap?: ReadonlyESMap | undefined; /** * Contains the map of exported modules ReferencedSet=exported module files from the file if module emit is enabled * Otherwise undefined */ - readonly exportedModulesMap?: ReadonlyMap | undefined; + readonly exportedModulesMap?: ReadonlyESMap | undefined; } export interface BuilderState { /** * Information of the file eg. its version, signature etc */ - fileInfos: Map; + fileInfos: ESMap; /** * Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled * Otherwise undefined * Thus non undefined value indicates, module emit */ - readonly referencedMap: ReadonlyMap | undefined; + readonly referencedMap: ReadonlyESMap | undefined; /** * Contains the map of exported modules ReferencedSet=exported module files from the file if module emit is enabled * Otherwise undefined */ - readonly exportedModulesMap: Map | undefined; + readonly exportedModulesMap: ESMap | undefined; /** * Map of files that have already called update signature. * That means hence forth these files are assumed to have @@ -83,7 +83,7 @@ namespace ts { * Exported modules to from declaration emit being computed. * This can contain false in the affected file path to specify that there are no exported module(types from other modules) for this file */ - export type ComputingExportedModulesMap = Map; + export type ComputingExportedModulesMap = ESMap; /** * Get the referencedFile from the imported module symbol @@ -192,7 +192,7 @@ namespace ts { /** * Returns true if oldState is reusable, that is the emitKind = module/non module has not changed */ - export function canReuseOldState(newReferencedMap: ReadonlyMap | undefined, oldState: Readonly | undefined) { + export function canReuseOldState(newReferencedMap: ReadonlyESMap | undefined, oldState: Readonly | undefined) { return oldState && !oldState.referencedMap === !newReferencedMap; } @@ -206,6 +206,9 @@ namespace ts { const hasCalledUpdateShapeSignature = new Set(); const useOldState = canReuseOldState(referencedMap, oldState); + // Ensure source files have parent pointers set + newProgram.getTypeChecker(); + // Create the reference map, and set the file infos for (const sourceFile of newProgram.getSourceFiles()) { const version = Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set"); @@ -258,7 +261,7 @@ namespace ts { /** * Gets the files affected by the path from the program */ - export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map, exportedModulesMapCache?: ComputingExportedModulesMap): readonly SourceFile[] { + export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: ESMap, exportedModulesMapCache?: ComputingExportedModulesMap): readonly SourceFile[] { // Since the operation could be cancelled, the signatures are always stored in the cache // They will be committed once it is safe to use them // eg when calling this api from tsserver, if there is no cancellation of the operation @@ -285,7 +288,7 @@ namespace ts { * Updates the signatures from the cache into state's fileinfo signatures * This should be called whenever it is safe to commit the state of the builder */ - export function updateSignaturesFromCache(state: BuilderState, signatureCache: Map) { + export function updateSignaturesFromCache(state: BuilderState, signatureCache: ESMap) { signatureCache.forEach((signature, path) => updateSignatureOfFile(state, signature, path)); } @@ -297,7 +300,7 @@ namespace ts { /** * Returns if the shape of the signature has changed since last emit */ - export function updateShapeSignature(state: Readonly, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ComputingExportedModulesMap) { + export function updateShapeSignature(state: Readonly, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ComputingExportedModulesMap) { Debug.assert(!!sourceFile); Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state"); @@ -518,7 +521,7 @@ namespace ts { /** * When program emits modular code, gets the files affected by the sourceFile whose shape has changed */ - function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined, exportedModulesMapCache: ComputingExportedModulesMap | undefined) { + function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined, exportedModulesMapCache: ComputingExportedModulesMap | undefined) { if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) { return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa0091f99523a..d20e460f37ba7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -134,7 +134,7 @@ namespace ts { EmptyObjectFacts = All, } - const typeofEQFacts: ReadonlyMap = createMapFromTemplate({ + const typeofEQFacts: ReadonlyESMap = new Map(getEntries({ string: TypeFacts.TypeofEQString, number: TypeFacts.TypeofEQNumber, bigint: TypeFacts.TypeofEQBigInt, @@ -143,9 +143,9 @@ namespace ts { undefined: TypeFacts.EQUndefined, object: TypeFacts.TypeofEQObject, function: TypeFacts.TypeofEQFunction - }); + })); - const typeofNEFacts: ReadonlyMap = createMapFromTemplate({ + const typeofNEFacts: ReadonlyESMap = new Map(getEntries({ string: TypeFacts.TypeofNEString, number: TypeFacts.TypeofNENumber, bigint: TypeFacts.TypeofNEBigInt, @@ -154,7 +154,7 @@ namespace ts { undefined: TypeFacts.NEUndefined, object: TypeFacts.TypeofNEObject, function: TypeFacts.TypeofNEFunction - }); + })); type TypeSystemEntity = Node | Symbol | Type | Signature; @@ -166,6 +166,7 @@ namespace ts { ImmediateBaseConstraint, EnumTagType, ResolvedTypeArguments, + ResolvedBaseTypes, } const enum CheckMode { @@ -261,7 +262,7 @@ namespace ts { return node.id; } - export function getSymbolId(symbol: Symbol): number { + export function getSymbolId(symbol: Symbol): SymbolId { if (!symbol.id) { symbol.id = nextSymbolId; nextSymbolId++; @@ -685,14 +686,14 @@ namespace ts { return res; } - const tupleTypes = createMap(); - const unionTypes = createMap(); - const intersectionTypes = createMap(); - const literalTypes = createMap(); - const indexedAccessTypes = createMap(); - const substitutionTypes = createMap(); + const tupleTypes = new Map(); + const unionTypes = new Map(); + const intersectionTypes = new Map(); + const literalTypes = new Map(); + const indexedAccessTypes = new Map(); + const substitutionTypes = new Map(); const evolvingArrayTypes: EvolvingArrayType[] = []; - const undefinedProperties = createMap() as UnderscoreEscapedMap; + const undefinedProperties: SymbolTable = new Map(); const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); @@ -753,7 +754,7 @@ namespace ts { const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, undefined, undefined); const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - emptyGenericType.instantiations = createMap(); + emptyGenericType.instantiations = new Map(); const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated @@ -778,7 +779,7 @@ namespace ts { const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); - const iterationTypesCache = createMap(); // cache for common IterationTypes instances + const iterationTypesCache = new Map(); // cache for common IterationTypes instances const noIterationTypes: IterationTypes = { get yieldType(): Type { return Debug.fail("Not supported"); }, get returnType(): Type { return Debug.fail("Not supported"); }, @@ -826,11 +827,11 @@ namespace ts { readonly firstFile: SourceFile; readonly secondFile: SourceFile; /** Key is symbol name. */ - readonly conflictingSymbols: Map; + readonly conflictingSymbols: ESMap; } /** Key is "/path/to/a.ts|/path/to/b.ts". */ - let amalgamatedDuplicates: Map | undefined; - const reverseMappedCache = createMap(); + let amalgamatedDuplicates: ESMap | undefined; + const reverseMappedCache = new Map(); let inInferTypeForHomomorphicMappedType = false; let ambientModulesCache: Symbol[] | undefined; /** @@ -839,7 +840,7 @@ namespace ts { * This is only used if there is no exact match. */ let patternAmbientModules: PatternAmbientModule[]; - let patternAmbientModuleAugmentations: Map | undefined; + let patternAmbientModuleAugmentations: ESMap | undefined; let globalObjectType: ObjectType; let globalFunctionType: ObjectType; @@ -883,7 +884,7 @@ namespace ts { let deferredGlobalOmitSymbol: Symbol; let deferredGlobalBigIntType: ObjectType; - const allPotentiallyUnusedIdentifiers = createMap(); // key is file name + const allPotentiallyUnusedIdentifiers = new Map(); // key is file name let flowLoopStart = 0; let flowLoopCount = 0; @@ -907,7 +908,7 @@ namespace ts { const mergedSymbols: Symbol[] = []; const symbolLinks: SymbolLinks[] = []; const nodeLinks: NodeLinks[] = []; - const flowLoopCaches: Map[] = []; + const flowLoopCaches: ESMap[] = []; const flowLoopNodes: FlowNode[] = []; const flowLoopKeys: string[] = []; const flowLoopTypes: Type[][] = []; @@ -923,26 +924,26 @@ namespace ts { const diagnostics = createDiagnosticCollection(); const suggestionDiagnostics = createDiagnosticCollection(); - const typeofTypesByName: ReadonlyMap = createMapFromTemplate({ + const typeofTypesByName: ReadonlyESMap = new Map(getEntries({ string: stringType, number: numberType, bigint: bigintType, boolean: booleanType, symbol: esSymbolType, undefined: undefinedType - }); + })); const typeofType = createTypeofType(); let _jsxNamespace: __String; let _jsxFactoryEntity: EntityName | undefined; let outofbandVarianceMarkerHandler: ((onlyUnreliable: boolean) => void) | undefined; - const subtypeRelation = createMap(); - const strictSubtypeRelation = createMap(); - const assignableRelation = createMap(); - const comparableRelation = createMap(); - const identityRelation = createMap(); - const enumRelation = createMap(); + const subtypeRelation = new Map(); + const strictSubtypeRelation = new Map(); + const assignableRelation = new Map(); + const comparableRelation = new Map(); + const identityRelation = new Map(); + const enumRelation = new Map(); const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -968,6 +969,11 @@ namespace ts { return file.localJsxFragmentNamespace = getFirstIdentifier(file.localJsxFragmentFactory).escapedText; } } + const entity = getJsxFragmentFactoryEntity(location); + if (entity) { + file.localJsxFragmentFactory = entity; + return file.localJsxFragmentNamespace = getFirstIdentifier(entity).escapedText; + } } else { if (file.localJsxNamespace) { @@ -1111,8 +1117,8 @@ namespace ts { result.parent = symbol.parent; if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = cloneMap(symbol.members); - if (symbol.exports) result.exports = cloneMap(symbol.exports); + if (symbol.members) result.members = new Map(symbol.members); + if (symbol.exports) result.exports = new Map(symbol.exports); recordMergedSymbol(result, symbol); return result; } @@ -1182,10 +1188,10 @@ namespace ts { if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) { const firstFile = comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === Comparison.LessThan ? sourceSymbolFile : targetSymbolFile; const secondFile = firstFile === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile; - const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => - ({ firstFile, secondFile, conflictingSymbols: createMap() })); - const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => - ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] })); + const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => + ({ firstFile, secondFile, conflictingSymbols: new Map() } as DuplicateInfoForFiles)); + const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName, () => + ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] } as DuplicateInfoForSymbol)); addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source); addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target); } @@ -1224,8 +1230,8 @@ namespace ts { } function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { - if (!hasEntries(first)) return second; - if (!hasEntries(second)) return first; + if (!first?.size) return second; + if (!second?.size) return first; const combined = createSymbolTable(); mergeSymbolTable(combined, first); mergeSymbolTable(combined, second); @@ -1273,7 +1279,7 @@ namespace ts { if (some(patternAmbientModules, module => mainModule === module.symbol)) { const merged = mergeSymbol(moduleAugmentation.symbol, mainModule, /*unidirectional*/ true); if (!patternAmbientModuleAugmentations) { - patternAmbientModuleAugmentations = createMap(); + patternAmbientModuleAugmentations = new Map(); } // moduleName will be a StringLiteral since this is not `declare global`. patternAmbientModuleAugmentations.set((moduleName as StringLiteral).text, merged); @@ -2573,8 +2579,8 @@ namespace ts { result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; - if (typeSymbol.members) result.members = cloneMap(typeSymbol.members); - if (valueSymbol.exports) result.exports = cloneMap(valueSymbol.exports); + if (typeSymbol.members) result.members = new Map(typeSymbol.members); + if (valueSymbol.exports) result.exports = new Map(valueSymbol.exports); return result; } @@ -3300,8 +3306,8 @@ namespace ts { result.originatingImport = referenceParent; if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; - if (symbol.members) result.members = cloneMap(symbol.members); - if (symbol.exports) result.exports = cloneMap(symbol.exports); + if (symbol.members) result.members = new Map(symbol.members); + if (symbol.exports) result.exports = new Map(symbol.exports); const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo); return result; @@ -3417,12 +3423,12 @@ namespace ts { if (!(symbol && symbol.exports && pushIfUnique(visitedSymbols, symbol))) { return; } - const symbols = cloneMap(symbol.exports); + const symbols = new Map(symbol.exports); // All export * declarations are collected in an __export symbol by the binder const exportStars = symbol.exports.get(InternalSymbolName.ExportStar); if (exportStars) { const nestedSymbols = createSymbolTable(); - const lookupTable = createMap() as ExportCollisionTrackerTable; + const lookupTable: ExportCollisionTrackerTable = new Map(); for (const node of exportStars.declarations) { const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier!); const exportedSymbols = visit(resolvedModule); @@ -3472,7 +3478,7 @@ namespace ts { function getAlternativeContainingModules(symbol: Symbol, enclosingDeclaration: Node): Symbol[] { const containingFile = getSourceFileOfNode(enclosingDeclaration); - const id = "" + getNodeId(containingFile); + const id = getNodeId(containingFile); const links = getSymbolLinks(symbol); let results: Symbol[] | undefined; if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) { @@ -3489,7 +3495,7 @@ namespace ts { results = append(results, resolvedModule); } if (length(results)) { - (links.extendedContainersByFile || (links.extendedContainersByFile = createMap())).set(id, results!); + (links.extendedContainersByFile || (links.extendedContainersByFile = new Map())).set(id, results!); return results!; } } @@ -3753,12 +3759,12 @@ namespace ts { return rightMeaning === SymbolFlags.Value ? SymbolFlags.Value : SymbolFlags.Namespace; } - function getAccessibleSymbolChain(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: Map = createMap()): Symbol[] | undefined { + function getAccessibleSymbolChain(symbol: Symbol | undefined, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean, visitedSymbolTablesMap: ESMap = new Map()): Symbol[] | undefined { if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) { return undefined; } - const id = "" + getSymbolId(symbol); + const id = getSymbolId(symbol); let visitedSymbolTables = visitedSymbolTablesMap.get(id); if (!visitedSymbolTables) { visitedSymbolTablesMap.set(id, visitedSymbolTables = []); @@ -4551,7 +4557,7 @@ namespace ts { context.visitedTypes = new Set(); } if (id && !context.symbolDepth) { - context.symbolDepth = createMap(); + context.symbolDepth = new Map(); } let depth: number | undefined; @@ -4572,8 +4578,8 @@ namespace ts { } function createTypeNodeFromObjectType(type: ObjectType): TypeNode { - if (isGenericMappedType(type)) { - return createMappedTypeNodeFromType(type); + if (isGenericMappedType(type) || (type as MappedType).containsError) { + return createMappedTypeNodeFromType(type as MappedType); } const resolved = resolveStructuredTypeMembers(type); @@ -5094,6 +5100,9 @@ namespace ts { if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) { parameterType = getOptionalType(parameterType); } + if ((context.flags & NodeBuilderFlags.NoUndefinedOptionalParameterType) && parameterDeclaration && !isJSDocParameterTag(parameterDeclaration) && isOptionalUninitializedParameter(parameterDeclaration)) { + parameterType = getTypeWithFacts(parameterType, TypeFacts.NEUndefined); + } const parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports); const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(factory.cloneNode) : undefined; @@ -5333,7 +5342,7 @@ namespace ts { moduleResolverHost, { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" }, )); - links.specifierCache = links.specifierCache || createMap(); + links.specifierCache ??= new Map(); links.specifierCache.set(contextFile.path, specifier); } return specifier; @@ -5455,7 +5464,7 @@ namespace ts { function typeParameterToName(type: TypeParameter, context: NodeBuilderContext) { if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && context.typeParameterNames) { - const cached = context.typeParameterNames.get("" + getTypeId(type)); + const cached = context.typeParameterNames.get(getTypeId(type)); if (cached) { return cached; } @@ -5475,7 +5484,7 @@ namespace ts { if (text !== rawtext) { result = factory.createIdentifier(text, result.typeArguments); } - (context.typeParameterNames || (context.typeParameterNames = createMap())).set("" + getTypeId(type), result); + (context.typeParameterNames || (context.typeParameterNames = new Map())).set(getTypeId(type), result); (context.typeParameterNamesByText || (context.typeParameterNamesByText = new Set())).add(result.escapedText as string); } return result; @@ -5567,15 +5576,14 @@ namespace ts { } } + function isStringNamed(d: Declaration) { + const name = getNameOfDeclaration(d); + return !!name && isStringLiteral(name); + } + function isSingleQuotedStringNamed(d: Declaration) { const name = getNameOfDeclaration(d); - if (name && isStringLiteral(name) && ( - name.singleQuote || - (!nodeIsSynthesized(name) && startsWith(getTextOfNode(name, /*includeTrivia*/ false), "'")) - )) { - return true; - } - return false; + return !!(name && isStringLiteral(name) && (name.singleQuote || !nodeIsSynthesized(name) && startsWith(getTextOfNode(name, /*includeTrivia*/ false), "'"))); } function getPropertyNameNodeForSymbol(symbol: Symbol, context: NodeBuilderContext) { @@ -5588,7 +5596,8 @@ namespace ts { return factory.createComputedPropertyName(factory.createPropertyAccessExpression(factory.createIdentifier("Symbol"), (symbol.escapedName as string).substr(3))); } const rawName = unescapeLeadingUnderscores(symbol.escapedName); - return createPropertyNameNodeForIdentifierOrLiteral(rawName, singleQuote); + const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed); + return createPropertyNameNodeForIdentifierOrLiteral(rawName, stringNamed, singleQuote); } // See getNameForSymbolFromNameType for a stringy equivalent @@ -5611,9 +5620,9 @@ namespace ts { } } - function createPropertyNameNodeForIdentifierOrLiteral(name: string, singleQuote?: boolean) { + function createPropertyNameNodeForIdentifierOrLiteral(name: string, stringNamed?: boolean, singleQuote?: boolean) { return isIdentifierText(name, compilerOptions.target) ? factory.createIdentifier(name) : - isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : + !stringNamed && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : factory.createStringLiteral(name, !!singleQuote); } @@ -5632,7 +5641,7 @@ namespace ts { // export const x: (x: T) => T // export const y: (x: T_1) => T_1 if (initial.typeParameterNames) { - initial.typeParameterNames = cloneMap(initial.typeParameterNames); + initial.typeParameterNames = new Map(initial.typeParameterNames); } if (initial.typeParameterNamesByText) { initial.typeParameterNamesByText = new Set(initial.typeParameterNamesByText); @@ -5878,12 +5887,12 @@ namespace ts { const enclosingDeclaration = context.enclosingDeclaration!; let results: Statement[] = []; const visitedSymbols = new Set(); - let deferredPrivates: Map | undefined; + let deferredPrivates: ESMap | undefined; const oldcontext = context; context = { ...oldcontext, usedSymbolNames: new Set(oldcontext.usedSymbolNames), - remappedSymbolNames: createMap(), + remappedSymbolNames: new Map(), tracker: { ...oldcontext.tracker, trackSymbol: (sym, decl, meaning) => { @@ -6091,7 +6100,7 @@ namespace ts { function visitSymbolTable(symbolTable: SymbolTable, suppressNewPrivateContext?: boolean, propertyAsAlias?: boolean) { const oldDeferredPrivates = deferredPrivates; if (!suppressNewPrivateContext) { - deferredPrivates = createMap(); + deferredPrivates = new Map(); } symbolTable.forEach((symbol: Symbol) => { serializeSymbol(symbol, /*isPrivate*/ false, !!propertyAsAlias); @@ -6290,7 +6299,7 @@ namespace ts { if (some(symbol.declarations, isParameterDeclaration)) return; Debug.assertIsDefined(deferredPrivates); getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol - deferredPrivates.set("" + getSymbolId(symbol), symbol); + deferredPrivates.set(getSymbolId(symbol), symbol); } function isExportingScope(enclosingDeclaration: Node) { @@ -6510,7 +6519,8 @@ namespace ts { } function isNamespaceMember(p: Symbol) { - return !(p.flags & SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && isClassLike(p.valueDeclaration.parent)); + return !!(p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias)) || + !(p.flags & SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && isClassLike(p.valueDeclaration.parent)); } function serializeAsClass(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { @@ -7059,9 +7069,10 @@ namespace ts { } function getUnusedName(input: string, symbol?: Symbol): string { - if (symbol) { - if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { - return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + const id = symbol ? getSymbolId(symbol) : undefined; + if (id) { + if (context.remappedSymbolNames!.has(id)) { + return context.remappedSymbolNames!.get(id)!; } } if (symbol) { @@ -7074,8 +7085,8 @@ namespace ts { input = `${original}_${i}`; } context.usedSymbolNames?.add(input); - if (symbol) { - context.remappedSymbolNames!.set("" + getSymbolId(symbol), input); + if (id) { + context.remappedSymbolNames!.set(id, input); } return input; } @@ -7099,12 +7110,13 @@ namespace ts { } function getInternalSymbolName(symbol: Symbol, localName: string) { - if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { - return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + const id = getSymbolId(symbol); + if (context.remappedSymbolNames!.has(id)) { + return context.remappedSymbolNames!.get(id)!; } localName = getNameCandidateWorker(symbol, localName); // The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up - context.remappedSymbolNames!.set("" + getSymbolId(symbol), localName); + context.remappedSymbolNames!.set(id, localName); return localName; } } @@ -7186,15 +7198,15 @@ namespace ts { // State encounteredError: boolean; visitedTypes: Set | undefined; - symbolDepth: Map | undefined; + symbolDepth: ESMap | undefined; inferTypeParameters: TypeParameter[] | undefined; approximateLength: number; truncating?: boolean; typeParameterSymbolList?: Set; - typeParameterNames?: Map; + typeParameterNames?: ESMap; typeParameterNamesByText?: Set; usedSymbolNames?: Set; - remappedSymbolNames?: Map; + remappedSymbolNames?: ESMap; } function isDefaultBindingContext(location: Node) { @@ -7480,6 +7492,8 @@ namespace ts { return !!(target).immediateBaseConstraint; case TypeSystemPropertyName.ResolvedTypeArguments: return !!(target as TypeReference).resolvedTypeArguments; + case TypeSystemPropertyName.ResolvedBaseTypes: + return !!(target as InterfaceType).baseTypesResolved; } return Debug.assertNever(propertyName); } @@ -7736,7 +7750,7 @@ namespace ts { } // Return the inferred type for a variable, parameter, or property declaration - function getTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement, includeOptionality: boolean): Type | undefined { + function getTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement | JSDocPropertyLikeTag, includeOptionality: boolean): Type | undefined { // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) { @@ -7759,6 +7773,7 @@ namespace ts { const isOptional = includeOptionality && ( isParameter(declaration) && isJSDocOptionalParameter(declaration) + || isOptionalJSDocPropertyLikeTag(declaration) || !isBindingElement(declaration) && !isVariableDeclaration(declaration) && !!declaration.questionToken); // Use type from type annotation if one is present @@ -7768,7 +7783,7 @@ namespace ts { } if ((noImplicitAny || isInJSFile(declaration)) && - declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && + isVariableDeclaration(declaration) && !isBindingPattern(declaration.name) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) { // If --noImplicitAny is on or the declaration is in a Javascript file, // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no @@ -7783,7 +7798,7 @@ namespace ts { } } - if (declaration.kind === SyntaxKind.Parameter) { + if (isParameter(declaration)) { const func = declaration.parent; // For a parameter of a set accessor, use the type of the get accessor if one is present if (func.kind === SyntaxKind.SetAccessor && !hasNonBindableDynamicName(func)) { @@ -7802,7 +7817,9 @@ namespace ts { if (isInJSFile(declaration)) { const typeTag = getJSDocType(func); if (typeTag && isFunctionTypeNode(typeTag)) { - return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration)); + const signature = getSignatureFromDeclaration(typeTag); + const pos = func.parameters.indexOf(declaration); + return declaration.dotDotDotToken ? getRestTypeAtPosition(signature, pos) : getTypeAtPosition(signature, pos); } } // Use contextual parameter type if one is available @@ -7811,16 +7828,16 @@ namespace ts { return addOptionality(type, isOptional); } } - else if (isInJSFile(declaration)) { - const containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), getDeclaredExpandoInitializer(declaration)); - if (containerObjectType) { - return containerObjectType; - } - } // Use the type of the initializer expression if one is present and the declaration is // not a parameter of a contextually typed function - if (declaration.initializer) { + if (hasOnlyExpressionInitializer(declaration) && !!declaration.initializer) { + if (isInJSFile(declaration) && !isParameter(declaration)) { + const containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), getDeclaredExpandoInitializer(declaration)); + if (containerObjectType) { + return containerObjectType; + } + } const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration)); return addOptionality(type, isOptional); } @@ -7985,13 +8002,13 @@ namespace ts { const exports = createSymbolTable(); while (isBinaryExpression(decl) || isPropertyAccessExpression(decl)) { const s = getSymbolOfNode(decl); - if (s && hasEntries(s.exports)) { + if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } decl = isBinaryExpression(decl) ? decl.parent : decl.parent.parent; } const s = getSymbolOfNode(decl); - if (s && hasEntries(s.exports)) { + if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, undefined, undefined); @@ -8240,7 +8257,7 @@ namespace ts { // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. - function getWidenedTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement, reportErrors?: boolean): Type { + function getWidenedTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement | JSDocPropertyLikeTag, reportErrors?: boolean): Type { return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true), declaration, reportErrors); } @@ -8347,8 +8364,7 @@ namespace ts { (isCallExpression(declaration) || (isPropertyAccessExpression(declaration) || isBindableStaticElementAccessExpression(declaration)) && isBinaryExpression(declaration.parent)))) { type = getWidenedTypeForAssignmentDeclaration(symbol); } - else if (isJSDocPropertyLikeTag(declaration) - || isPropertyAccessExpression(declaration) + else if (isPropertyAccessExpression(declaration) || isElementAccessExpression(declaration) || isIdentifier(declaration) || isStringLiteralLike(declaration) @@ -8382,7 +8398,8 @@ namespace ts { || isPropertyDeclaration(declaration) || isPropertySignature(declaration) || isVariableDeclaration(declaration) - || isBindingElement(declaration)) { + || isBindingElement(declaration) + || isJSDocPropertyLikeTag(declaration)) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); } // getTypeOfSymbol dispatches some JS merges incorrectly because their symbol flags are not mutually exclusive. @@ -8751,6 +8768,12 @@ namespace ts { (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; + case SyntaxKind.JSDocParameterTag: + const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag); + if (paramSymbol) { + node = paramSymbol.valueDeclaration; + } + break; } } } @@ -8897,22 +8920,36 @@ namespace ts { return resolvedImplementsTypes; } + function reportCircularBaseType(node: Node, type: Type) { + error(node, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); + } + function getBaseTypes(type: InterfaceType): BaseType[] { - if (!type.resolvedBaseTypes) { - if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [getTupleBaseType(type)]; - } - else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { - if (type.symbol.flags & SymbolFlags.Class) { - resolveBaseTypesOfClass(type); + if (!type.baseTypesResolved) { + if (pushTypeResolution(type, TypeSystemPropertyName.ResolvedBaseTypes)) { + if (type.objectFlags & ObjectFlags.Tuple) { + type.resolvedBaseTypes = [getTupleBaseType(type)]; } - if (type.symbol.flags & SymbolFlags.Interface) { - resolveBaseTypesOfInterface(type); + else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + if (type.symbol.flags & SymbolFlags.Class) { + resolveBaseTypesOfClass(type); + } + if (type.symbol.flags & SymbolFlags.Interface) { + resolveBaseTypesOfInterface(type); + } + } + else { + Debug.fail("type must be class or interface"); + } + if (!popTypeResolution()) { + for (const declaration of type.symbol.declarations) { + if (declaration.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.InterfaceDeclaration) { + reportCircularBaseType(declaration, type); + } + } } } - else { - Debug.fail("type must be class or interface"); - } + type.baseTypesResolved = true; } return type.resolvedBaseTypes; } @@ -9021,7 +9058,7 @@ namespace ts { } } else { - error(declaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); + reportCircularBaseType(declaration, type); } } else { @@ -9086,7 +9123,7 @@ namespace ts { type.typeParameters = concatenate(outerTypeParameters, localTypeParameters); type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; - (type).instantiations = createMap(); + (type).instantiations = new Map(); (type).instantiations.set(getTypeListId(type.typeParameters), type); (type).target = type; (type).resolvedTypeArguments = type.typeParameters; @@ -9118,7 +9155,7 @@ namespace ts { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; - links.instantiations = createMap(); + links.instantiations = new Map(); links.instantiations.set(getTypeListId(typeParameters), type); } } @@ -9781,7 +9818,7 @@ namespace ts { const restParams = map(elementTypes, (t, i) => { // Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]); - const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i); + const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i, restType); const flags = restType.target.elementFlags[i]; const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter : flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0; @@ -10112,7 +10149,7 @@ namespace ts { if (symbol.exports) { members = getExportsOfSymbol(symbol); if (symbol === globalThisSymbol) { - const varsOnly = createMap() as SymbolTable; + const varsOnly = new Map() as SymbolTable; members.forEach(p => { if (!(p.flags & SymbolFlags.BlockScoped)) { varsOnly.set(p.escapedName, p); @@ -10253,22 +10290,32 @@ namespace ts { // Otherwise, for type string create a string index signature. if (isTypeUsableAsPropertyName(t)) { const propName = getPropertyNameFromType(t); - const modifiersProp = getPropertyOfType(modifiersType, propName); - const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || - !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); - const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || - !(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp)); - const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; - const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, - CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)); - prop.mappedType = type; - prop.mapper = templateMapper; - if (modifiersProp) { - prop.syntheticOrigin = modifiersProp; - prop.declarations = modifiersProp.declarations; - } - prop.nameType = t; - members.set(propName, prop); + // String enum members from separate enums with identical values + // are distinct types with the same property name. Make the resulting + // property symbol's name type be the union of those enum member types. + const existingProp = members.get(propName) as MappedSymbol | undefined; + if (existingProp) { + existingProp.nameType = getUnionType([existingProp.nameType!, t]); + existingProp.mapper = appendTypeMapping(type.mapper, typeParameter, existingProp.nameType); + } + else { + const modifiersProp = getPropertyOfType(modifiersType, propName); + const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || + !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); + const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || + !(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp)); + const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; + const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, + CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)); + prop.mappedType = type; + if (modifiersProp) { + prop.syntheticOrigin = modifiersProp; + prop.declarations = modifiersProp.declarations; + } + prop.nameType = t; + prop.mapper = templateMapper; + members.set(propName, prop); + } } else if (t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) { const propType = instantiateType(templateType, templateMapper); @@ -10286,6 +10333,7 @@ namespace ts { function getTypeOfMappedSymbol(symbol: MappedSymbol) { if (!symbol.type) { if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { + symbol.mappedType.containsError = true; return errorType; } const templateType = getTemplateTypeFromMappedType(symbol.mappedType.target || symbol.mappedType); @@ -10819,7 +10867,7 @@ namespace ts { function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { let singleProp: Symbol | undefined; - let propSet: Map | undefined; + let propSet: ESMap | undefined; let indexTypes: Type[] | undefined; const isUnion = containingType.flags & TypeFlags.Union; // Flags we want to propagate to the result if they exist in all source symbols @@ -10843,10 +10891,10 @@ namespace ts { } else if (prop !== singleProp) { if (!propSet) { - propSet = createMap(); - propSet.set("" + getSymbolId(singleProp), singleProp); + propSet = new Map(); + propSet.set(getSymbolId(singleProp), singleProp); } - const id = "" + getSymbolId(prop); + const id = getSymbolId(prop); if (!propSet.has(id)) { propSet.set(id, prop); } @@ -11158,8 +11206,8 @@ namespace ts { return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol; } - function isOptionalParameter(node: ParameterDeclaration | JSDocParameterTag) { - if (hasQuestionToken(node) || isOptionalJSDocParameterTag(node) || isJSDocOptionalParameter(node)) { + function isOptionalParameter(node: ParameterDeclaration | JSDocParameterTag | JSDocPropertyTag) { + if (hasQuestionToken(node) || isOptionalJSDocPropertyLikeTag(node) || isJSDocOptionalParameter(node)) { return true; } @@ -11179,8 +11227,8 @@ namespace ts { return false; } - function isOptionalJSDocParameterTag(node: Node): node is JSDocParameterTag { - if (!isJSDocParameterTag(node)) { + function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag { + if (!isJSDocPropertyLikeTag(node)) { return false; } const { isBracketed, typeExpression } = node; @@ -11288,7 +11336,7 @@ namespace ts { } // Record a new minimum argument count if this is not an optional parameter - const isOptionalParameter = isOptionalJSDocParameterTag(param) || + const isOptionalParameter = isOptionalJSDocPropertyLikeTag(param) || param.initializer || param.questionToken || param.dotDotDotToken || iife && parameters.length > iife.arguments.length && !type || isJSDocOptionalParameter(param); @@ -11562,7 +11610,7 @@ namespace ts { } function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: readonly Type[] | undefined): Signature { - const instantiations = signature.instantiations || (signature.instantiations = createMap()); + const instantiations = signature.instantiations || (signature.instantiations = new Map()); const id = getTypeListId(typeArguments); let instantiation = instantiations.get(id); if (!instantiation) { @@ -12521,7 +12569,7 @@ namespace ts { type.typeParameters = typeParameters; type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; - type.instantiations = createMap(); + type.instantiations = new Map(); type.instantiations.set(getTypeListId(type.typeParameters), type); type.target = type; type.resolvedTypeArguments = type.typeParameters; @@ -12647,7 +12695,7 @@ namespace ts { return strictNullChecks ? getOptionalType(type) : type; } - function getTypeId(type: Type) { + function getTypeId(type: Type): TypeId { return type.id; } @@ -12880,7 +12928,7 @@ namespace ts { return links.resolvedType; } - function addTypeToIntersection(typeSet: Map, includes: TypeFlags, type: Type) { + function addTypeToIntersection(typeSet: ESMap, includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Intersection) { return addTypesToIntersection(typeSet, includes, (type).types); @@ -12910,7 +12958,7 @@ namespace ts { // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. - function addTypesToIntersection(typeSet: Map, includes: TypeFlags, types: readonly Type[]) { + function addTypesToIntersection(typeSet: ESMap, includes: TypeFlags, types: readonly Type[]) { for (const type of types) { includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type)); } @@ -13027,7 +13075,7 @@ namespace ts { // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { - const typeMembershipMap: Map = createMap(); + const typeMembershipMap: ESMap = new Map(); const includes = addTypesToIntersection(typeMembershipMap, 0, types); const typeSet: Type[] = arrayFrom(typeMembershipMap.values()); // An intersection type is considered empty if it contains @@ -13274,13 +13322,19 @@ namespace ts { undefined; } - function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) { + function isUncalledFunctionReference(node: Node, symbol: Symbol) { + return !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) + || !isCallLikeExpression(findAncestor(node, n => !isAccessExpression(n)) || node.parent) + && every(symbol.declarations, d => !isFunctionLike(d) || !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated)); + } + + function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags, reportDeprecated?: boolean) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = accessNode && isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode); if (propName !== undefined) { const prop = getPropertyOfType(objectType, propName); if (prop) { - if (accessNode && prop.flags & SymbolFlags.Deprecated) { + if (reportDeprecated && accessNode && prop.valueDeclaration?.flags & NodeFlags.Deprecated && isUncalledFunctionReference(accessNode, prop)) { const deprecatedNode = accessExpression?.argumentExpression ?? (isIndexedAccessTypeNode(accessNode) ? accessNode.indexType : accessNode); errorOrSuggestion(/* isError */ false, deprecatedNode, Diagnostics._0_is_deprecated, propName as string); } @@ -13650,7 +13704,7 @@ namespace ts { } return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments) : getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } - return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol); + return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol, /* reportDeprecated */ true); } function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { @@ -13821,7 +13875,7 @@ namespace ts { }; links.resolvedType = getConditionalType(root, /*mapper*/ undefined); if (outerTypeParameters) { - root.instantiations = createMap(); + root.instantiations = new Map(); root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType); } } @@ -14059,7 +14113,7 @@ namespace ts { } const members = createSymbolTable(); - const skippedPrivateMembers = createUnderscoreEscapedMap(); + const skippedPrivateMembers = new Set<__String>(); let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; if (left === emptyObjectType) { @@ -14074,7 +14128,7 @@ namespace ts { for (const rightProp of getPropertiesOfType(right)) { if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { - skippedPrivateMembers.set(rightProp.escapedName, true); + skippedPrivateMembers.add(rightProp.escapedName); } else if (isSpreadableProperty(rightProp)) { members.set(rightProp.escapedName, getSpreadSymbol(rightProp, readonly)); @@ -14371,11 +14425,12 @@ namespace ts { return getTypeFromInferTypeNode(node); case SyntaxKind.ImportType: return getTypeFromImportTypeNode(node); - // This function assumes that an identifier or qualified name is a type expression + // This function assumes that an identifier, qualified name, or property access expression is a type expression // Callers should first ensure this by calling `isPartOfTypeNode` // TODO(rbuckton): These aren't valid TypeNodes, but we treat them as such because of `isPartOfTypeNode`, which returns `true` for things that aren't `TypeNode`s. case SyntaxKind.Identifier as TypeNodeSyntaxKind: case SyntaxKind.QualifiedName as TypeNodeSyntaxKind: + case SyntaxKind.PropertyAccessExpression as TypeNodeSyntaxKind: const symbol = getSymbolAtLocation(node); return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType; default: @@ -14560,24 +14615,14 @@ namespace ts { function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper) { const target = type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; - const node = type.objectFlags & ObjectFlags.Reference ? (type).node! : type.symbol.declarations[0]; - const links = getNodeLinks(node); + const declaration = type.objectFlags & ObjectFlags.Reference ? (type).node! : type.symbol.declarations[0]; + const links = getNodeLinks(declaration); let typeParameters = links.outerTypeParameters; if (!typeParameters) { // The first time an anonymous type is instantiated we compute and store a list of the type // parameters that are in scope (and therefore potentially referenced). For type literals that // aren't the right hand side of a generic type alias declaration we optimize by reducing the // set of type parameters to those that are possibly referenced in the literal. - let declaration = node; - if (isInJSFile(declaration)) { - const paramTag = findAncestor(declaration, isJSDocParameterTag); - if (paramTag) { - const paramSymbol = getParameterSymbolFromJSDoc(paramTag); - if (paramSymbol) { - declaration = paramSymbol.valueDeclaration; - } - } - } let outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true); if (isJSConstructor(declaration)) { const templateTagParameters = getTypeParametersFromDeclaration(declaration as DeclarationWithTypeParameters); @@ -14589,7 +14634,7 @@ namespace ts { typeParameters; links.outerTypeParameters = typeParameters; if (typeParameters.length) { - links.instantiations = createMap(); + links.instantiations = new Map(); links.instantiations.set(getTypeListId(typeParameters), target); } } @@ -15067,7 +15112,7 @@ namespace ts { function checkTypeRelatedToAndOptionallyElaborate( source: Type, target: Type, - relation: Map, + relation: ESMap, errorNode: Node | undefined, expr: Expression | undefined, headMessage: DiagnosticMessage | undefined, @@ -15089,7 +15134,7 @@ namespace ts { node: Expression | undefined, source: Type, target: Type, - relation: Map, + relation: ESMap, headMessage: DiagnosticMessage | undefined, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined @@ -15126,7 +15171,7 @@ namespace ts { node: Expression, source: Type, target: Type, - relation: Map, + relation: ESMap, headMessage: DiagnosticMessage | undefined, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined @@ -15155,7 +15200,7 @@ namespace ts { node: ArrowFunction, source: Type, target: Type, - relation: Map, + relation: ESMap, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined ): boolean { @@ -15242,7 +15287,7 @@ namespace ts { iterator: ElaborationIterator, source: Type, target: Type, - relation: Map, + relation: ESMap, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined ) { @@ -15356,7 +15401,7 @@ namespace ts { node: JsxAttributes, source: Type, target: Type, - relation: Map, + relation: ESMap, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined ) { @@ -15457,7 +15502,7 @@ namespace ts { node: ArrayLiteralExpression, source: Type, target: Type, - relation: Map, + relation: ESMap, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined ) { @@ -15510,7 +15555,7 @@ namespace ts { node: ObjectLiteralExpression, source: Type, target: Type, - relation: Map, + relation: ESMap, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, errorOutputContainer: { errors?: Diagnostic[], skipLogging?: boolean } | undefined ) { @@ -15801,7 +15846,7 @@ namespace ts { return true; } - function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { + function isSimpleTypeRelatedTo(source: Type, target: Type, relation: ESMap, errorReporter?: ErrorReporter) { const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -15838,7 +15883,7 @@ namespace ts { return false; } - function isTypeRelatedTo(source: Type, target: Type, relation: Map) { + function isTypeRelatedTo(source: Type, target: Type, relation: ESMap) { if (isFreshLiteralType(source)) { source = (source).regularType; } @@ -15901,7 +15946,7 @@ namespace ts { function checkTypeRelatedTo( source: Type, target: Type, - relation: Map, + relation: ESMap, errorNode: Node | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, @@ -16120,6 +16165,7 @@ namespace ts { if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { generalizedSource = getBaseTypeOfLiteralType(source); + Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource); } @@ -17213,14 +17259,14 @@ namespace ts { // Compute the set of types for each discriminant property. const sourceDiscriminantTypes: Type[][] = new Array(sourcePropertiesFiltered.length); - const excludedProperties = createUnderscoreEscapedMap(); + const excludedProperties = new Set<__String>(); for (let i = 0; i < sourcePropertiesFiltered.length; i++) { const sourceProperty = sourcePropertiesFiltered[i]; const sourcePropertyType = getTypeOfSymbol(sourceProperty); sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union ? (sourcePropertyType as UnionType).types : [sourcePropertyType]; - excludedProperties.set(sourceProperty.escapedName, true); + excludedProperties.add(sourceProperty.escapedName); } // Match each combination of the cartesian product of discriminant properties to one or more @@ -17262,7 +17308,11 @@ namespace ts { result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false); if (result) { result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); - if (result) { + // Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the + // element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems + // with index type assignability as the types for the excluded discriminants are still included + // in the index type. + if (result && !(isTupleType(source) && isTupleType(type))) { result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); } } @@ -17275,7 +17325,7 @@ namespace ts { return result; } - function excludeProperties(properties: Symbol[], excludedProperties: UnderscoreEscapedMap | undefined) { + function excludeProperties(properties: Symbol[], excludedProperties: Set<__String> | undefined) { if (!excludedProperties || properties.length === 0) return properties; let result: Symbol[] | undefined; for (let i = 0; i < properties.length; i++) { @@ -17444,7 +17494,7 @@ namespace ts { // No array like or unmatched property error - just issue top level error (errorInfo = undefined) } - function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: UnderscoreEscapedMap | undefined, intersectionState: IntersectionState): Ternary { + function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: Set<__String> | undefined, intersectionState: IntersectionState): Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target, excludedProperties); } @@ -17487,6 +17537,7 @@ namespace ts { for (let i = 0; i < maxArity; i++) { const targetFlags = i < targetArity ? target.target.elementFlags[i] : targetRestFlag; const sourceFlags = isTupleType(source) && i < sourceArity ? source.target.elementFlags[i] : sourceRestFlag; + let canExcludeDiscriminants = !!excludedProperties; if (sourceFlags && targetFlags) { if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic) || (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable))) { @@ -17503,6 +17554,15 @@ namespace ts { return Ternary.False; } } + // We can only exclude discriminant properties if we have not yet encountered a variable-length element. + if (canExcludeDiscriminants) { + if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) { + canExcludeDiscriminants = false; + } + if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) { + continue; + } + } const sourceType = getTypeArguments(source)[Math.min(i, sourceArity - 1)]; const targetType = getTypeArguments(target)[Math.min(i, targetArity - 1)]; const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType; @@ -17563,7 +17623,7 @@ namespace ts { return result; } - function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: UnderscoreEscapedMap | undefined): Ternary { + function propertiesIdenticalTo(source: Type, target: Type, excludedProperties: Set<__String> | undefined): Ternary { if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { return Ternary.False; } @@ -17823,6 +17883,13 @@ namespace ts { } function typeCouldHaveTopLevelSingletonTypes(type: Type): boolean { + // Okay, yes, 'boolean' is a union of 'true | false', but that's not useful + // in error reporting scenarios. If you need to use this function but that detail matters, + // feel free to add a flag. + if (type.flags & TypeFlags.Boolean) { + return false; + } + if (type.flags & TypeFlags.UnionOrIntersection) { return !!forEach((type as IntersectionType).types, typeCouldHaveTopLevelSingletonTypes); } @@ -18023,7 +18090,7 @@ namespace ts { * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. * For other cases, the types ids are used. */ - function getRelationKey(source: Type, target: Type, intersectionState: IntersectionState, relation: Map) { + function getRelationKey(source: Type, target: Type, intersectionState: IntersectionState, relation: ESMap) { if (relation === identityRelation && source.id > target.id) { const temp = source; source = target; @@ -18451,8 +18518,8 @@ namespace ts { return restType && createArrayType(restType); } - function getEndLengthOfType(type: Type) { - return isTupleType(type) ? getTypeReferenceArity(type) - findLastIndex(type.target.elementFlags, f => !!(f & ElementFlags.Variable)) - 1 : 0; + function getEndLengthOfType(type: Type, flags: ElementFlags) { + return isTupleType(type) ? getTypeReferenceArity(type) - findLastIndex(type.target.elementFlags, f => !(f & flags)) - 1 : 0; } function getElementTypeOfSliceOfTupleType(type: TupleTypeReference, index: number, endSkipCount = 0, writing = false) { @@ -18689,7 +18756,7 @@ namespace ts { function getPropertiesOfContext(context: WideningContext): Symbol[] { if (!context.resolvedProperties) { - const names = createMap() as UnderscoreEscapedMap; + const names = new Map() as UnderscoreEscapedMap; for (const t of getSiblingsOfContext(context)) { if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) { for (const prop of getPropertiesOfType(t)) { @@ -19207,7 +19274,7 @@ namespace ts { function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) { let symbolOrTypeStack: (Symbol | Type)[]; - let visited: Map; + let visited: ESMap; let bivariant = false; let propagationType: Type; let inferencePriority = InferencePriority.MaxValue; @@ -19441,7 +19508,7 @@ namespace ts { inferencePriority = Math.min(inferencePriority, status); return; } - (visited || (visited = createMap())).set(key, InferencePriority.Circularity); + (visited || (visited = new Map())).set(key, InferencePriority.Circularity); const saveInferencePriority = inferencePriority; inferencePriority = InferencePriority.MaxValue; action(source, target); @@ -19713,8 +19780,8 @@ namespace ts { const sourceRestType = !isTupleType(source) || sourceArity > 0 && source.target.elementFlags[sourceArity - 1] & ElementFlags.Rest ? getTypeArguments(source)[sourceArity - 1] : undefined; const endLength = !(target.target.combinedFlags & ElementFlags.Variable) ? 0 : - sourceRestType ? getEndLengthOfType(target) : - Math.min(getEndLengthOfType(source), getEndLengthOfType(target)); + sourceRestType ? getEndLengthOfType(target, ElementFlags.Required) : + Math.min(getEndLengthOfType(source, ElementFlags.Required | ElementFlags.Optional), getEndLengthOfType(target, ElementFlags.Required)); const sourceEndLength = sourceRestType ? 0 : endLength; // Infer between starting fixed elements. for (let i = 0; i < startLength; i++) { @@ -20570,7 +20637,7 @@ namespace ts { } function createFlowType(type: Type, incomplete: boolean): FlowType { - return incomplete ? { flags: 0, type } : type; + return incomplete ? { flags: 0, type: type.flags & TypeFlags.Never ? silentNeverType : type } : type; } // An evolving array type tracks the element types that have so far been seen in an @@ -20591,7 +20658,7 @@ namespace ts { // we defer subtype reduction until the evolving array type is finalized into a manifest // array type. function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType { - const elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node)); + const elementType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node))); return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType])); } @@ -21158,9 +21225,7 @@ namespace ts { if (narrowedType === nonEvolvingType) { return flowType; } - const incomplete = isIncomplete(flowType); - const resultType = incomplete && narrowedType.flags & TypeFlags.Never ? silentNeverType : narrowedType; - return createFlowType(resultType, incomplete); + return createFlowType(narrowedType, isIncomplete(flowType)); } function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { @@ -21249,7 +21314,7 @@ namespace ts { // If we have previously computed the control flow type for the reference at // this flow loop junction, return the cached type. const id = getFlowNodeId(flow); - const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap()); + const cache = flowLoopCaches[id] || (flowLoopCaches[id] = new Map()); const key = getOrSetCacheKey(); if (!key) { // No cache key is generated when binding patterns are in unnarrowable situations @@ -21498,15 +21563,11 @@ namespace ts { assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; return getTypeWithFacts(type, facts); } - if (type.flags & TypeFlags.NotUnionOrUnit) { - return type; - } if (assumeTrue) { const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? (t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType)) : t => areTypesComparable(t, valueType); - const narrowedType = filterType(type, filterFn); - return narrowedType.flags & TypeFlags.Never ? type : replacePrimitivesWithLiterals(narrowedType, valueType); + return replacePrimitivesWithLiterals(filterType(type, filterFn), valueType); } if (isUnitType(valueType)) { const regularType = getRegularTypeOfLiteralType(valueType); @@ -21782,6 +21843,12 @@ namespace ts { emptyObjectType; } + // We can't narrow a union based off instanceof without negated types see #31576 for more info + if (!assumeTrue && rightType.flags & TypeFlags.Union) { + const nonConstructorTypeInUnion = find((rightType).types, (t) => !isConstructorType(t)); + if (!nonConstructorTypeInUnion) return type; + } + return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); } @@ -22043,9 +22110,8 @@ namespace ts { const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); let declaration: Declaration | undefined = localOrExportSymbol.valueDeclaration; - const target = (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); - if (target.flags & SymbolFlags.Deprecated) { - errorOrSuggestion(/* isError */ false, node, Diagnostics._0_is_deprecated, node.escapedText as string); + if (declaration && getCombinedNodeFlags(declaration) & NodeFlags.Deprecated && isUncalledFunctionReference(node.parent, localOrExportSymbol)) { + errorOrSuggestion(/* isError */ false, node, Diagnostics._0_is_deprecated, node.escapedText as string);; } if (localOrExportSymbol.flags & SymbolFlags.Class) { // Due to the emit for class decorators, any reference to the class from inside of the class body @@ -22399,30 +22465,23 @@ namespace ts { const isInJS = isInJSFile(node); if (isFunctionLike(container) && (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) { + let thisType = getThisTypeOfDeclaration(container) || isInJS && getTypeForThisExpressionFromJSDoc(container); // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated. // If this is a function in a JS file, it might be a class method. - const className = getClassNameFromPrototypeMethod(container); - if (isInJS && className) { - const classSymbol = checkExpression(className).symbol; - if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { - const classType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType; - if (classType) { - return getFlowTypeOfReference(node, classType); + if (!thisType) { + const className = getClassNameFromPrototypeMethod(container); + if (isInJS && className) { + const classSymbol = checkExpression(className).symbol; + if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { + thisType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType; } } - } - // Check if it's a constructor definition, can be either a variable decl or function decl - // i.e. - // * /** @constructor */ function [name]() { ... } - // * /** @constructor */ var x = function() { ... } - else if (isInJS && - (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) && - getJSDocClassTag(container)) { - const classType = (getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)) as InterfaceType).thisType!; - return getFlowTypeOfReference(node, classType); + else if (isJSConstructor(container)) { + thisType = (getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)) as InterfaceType).thisType; + } + thisType ||= getContextualThisParameterType(container); } - const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { return getFlowTypeOfReference(node, thisType); } @@ -22434,12 +22493,6 @@ namespace ts { return getFlowTypeOfReference(node, type); } - if (isInJS) { - const type = getTypeForThisExpressionFromJSDoc(container); - if (type && type !== errorType) { - return getFlowTypeOfReference(node, type); - } - } if (isSourceFile(container)) { // look up in the source file's locals or exports if (container.commonJsModuleIndicator) { @@ -23408,7 +23461,7 @@ namespace ts { return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: case SyntaxKind.AsExpression: - return isConstTypeReference((parent).type) ? undefined : getTypeFromTypeNode((parent).type); + return isConstTypeReference((parent).type) ? tryFindWhenConstTypeReference(parent) : getTypeFromTypeNode((parent).type); case SyntaxKind.BinaryExpression: return getContextualTypeForBinaryOperand(node, contextFlags); case SyntaxKind.PropertyAssignment: @@ -23441,6 +23494,13 @@ namespace ts { return getContextualJsxElementAttributesType(parent, contextFlags); } return undefined; + + function tryFindWhenConstTypeReference(node: Expression) { + if(isCallLikeExpression(node.parent)){ + return getContextualTypeForArgument(node.parent, node); + } + return undefined; + } } function getInferenceContext(node: Node) { @@ -23824,10 +23884,15 @@ namespace ts { return links.resolvedType; } + function isSymbolWithNumericName(symbol: Symbol) { + const firstDecl = symbol.declarations?.[0]; + return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); + } + function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo { const propTypes: Type[] = []; for (let i = offset; i < properties.length; i++) { - if (kind === IndexKind.String || isNumericName(node.properties[i].name!)) { + if (kind === IndexKind.String || isSymbolWithNumericName(properties[i])) { propTypes.push(getTypeOfSymbol(properties[i])); } } @@ -23880,8 +23945,7 @@ namespace ts { } let offset = 0; - for (let i = 0; i < node.properties.length; i++) { - const memberDecl = node.properties[i]; + for (const memberDecl of node.properties) { let member = getSymbolOfNode(memberDecl); const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ? checkComputedPropertyName(memberDecl.name) : undefined; @@ -23889,7 +23953,10 @@ namespace ts { memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment || isObjectLiteralMethod(memberDecl)) { let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : - memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) : + // avoid resolving the left side of the ShorthandPropertyAssignment outside of the destructuring + // for error recovery purposes. For example, if a user wrote `{ a = 100 }` instead of `{ a: 100 }`. + // we don't want to say "could not find 'a'". + memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode) : checkObjectLiteralMethod(memberDecl, checkMode); if (isInJavascript) { const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl); @@ -23965,7 +24032,7 @@ namespace ts { checkSpreadPropOverrides(type, allPropertiesTable, memberDecl); } spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext); - offset = i + 1; + offset = propertiesArray.length; continue; } else { @@ -24585,6 +24652,7 @@ namespace ts { if (isNodeOpeningLikeElement) { const jsxOpeningLikeNode = node as JsxOpeningLikeElement; const sig = getResolvedSignature(jsxOpeningLikeNode); + checkDeprecatedSignature(sig, node); checkJsxReturnAssignableToAppropriateBound(getJsxReferenceKind(jsxOpeningLikeNode), getReturnTypeOfSignature(sig), jsxOpeningLikeNode); } } @@ -25013,7 +25081,7 @@ namespace ts { propType = indexInfo.type; } else { - if (prop.flags & SymbolFlags.Deprecated) { + if (prop.valueDeclaration?.flags & NodeFlags.Deprecated && isUncalledFunctionReference(node, prop)) { errorOrSuggestion(/* isError */ false, right, Diagnostics._0_is_deprecated, right.escapedText as string); } @@ -25769,13 +25837,6 @@ namespace ts { } } - const thisType = getThisTypeOfSignature(signature); - if (thisType) { - const thisArgumentNode = getThisArgumentOfCall(node); - const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; - inferTypes(context.inferences, thisArgumentType, thisType); - } - const restType = getNonArrayRestType(signature); const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; if (restType && restType.flags & TypeFlags.TypeParameter) { @@ -25784,6 +25845,14 @@ namespace ts { info.impliedArity = findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined; } } + + const thisType = getThisTypeOfSignature(signature); + if (thisType) { + const thisArgumentNode = getThisArgumentOfCall(node); + const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; + inferTypes(context.inferences, thisArgumentType, thisType); + } + for (let i = 0; i < argCount; i++) { const arg = args[i]; if (arg.kind !== SyntaxKind.OmittedExpression) { @@ -25899,7 +25968,7 @@ namespace ts { function checkApplicableSignatureForJsxOpeningLikeElement( node: JsxOpeningLikeElement, signature: Signature, - relation: Map, + relation: ESMap, checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, @@ -25999,7 +26068,7 @@ namespace ts { node: CallLikeExpression, args: readonly Expression[], signature: Signature, - relation: Map, + relation: ESMap, checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, @@ -26523,7 +26592,7 @@ namespace ts { return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray); - function chooseOverload(candidates: Signature[], relation: Map, signatureHelpTrailingComma = false) { + function chooseOverload(candidates: Signature[], relation: ESMap, signatureHelpTrailingComma = false) { candidatesForArgumentError = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined; @@ -27339,7 +27408,7 @@ namespace ts { // If the symbol of the node has members, treat it like a constructor. const symbol = getSymbolOfNode(func); - return !!symbol && hasEntries(symbol.members); + return !!symbol?.members?.size; } return false; } @@ -27347,21 +27416,21 @@ namespace ts { function mergeJSSymbols(target: Symbol, source: Symbol | undefined) { if (source) { const links = getSymbolLinks(source); - if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) { + if (!links.inferredClassSymbol || !links.inferredClassSymbol.has(getSymbolId(target))) { const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol; inferred.exports = inferred.exports || createSymbolTable(); inferred.members = inferred.members || createSymbolTable(); inferred.flags |= source.flags & SymbolFlags.Class; - if (hasEntries(source.exports)) { + if (source.exports?.size) { mergeSymbolTable(inferred.exports, source.exports); } - if (hasEntries(source.members)) { + if (source.members?.size) { mergeSymbolTable(inferred.members, source.members); } - (links.inferredClassSymbol || (links.inferredClassSymbol = createMap())).set("" + getSymbolId(inferred), inferred); + (links.inferredClassSymbol || (links.inferredClassSymbol = new Map())).set(getSymbolId(inferred), inferred); return inferred; } - return links.inferredClassSymbol.get("" + getSymbolId(target)); + return links.inferredClassSymbol.get(getSymbolId(target)); } } @@ -27404,6 +27473,8 @@ namespace ts { return nonInferrableType; } + checkDeprecatedSignature(signature, node); + if (node.expression.kind === SyntaxKind.SuperKeyword) { return voidType; } @@ -27452,7 +27523,7 @@ namespace ts { const decl = getDeclarationOfExpando(node); if (decl) { const jsSymbol = getSymbolOfNode(decl); - if (jsSymbol && hasEntries(jsSymbol.exports)) { + if (jsSymbol?.exports?.size) { const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined); jsAssignmentType.objectFlags |= ObjectFlags.JSLiteral; return getIntersectionType([returnType, jsAssignmentType]); @@ -27463,6 +27534,12 @@ namespace ts { return returnType; } + function checkDeprecatedSignature(signature: Signature, node: Node) { + if (signature.declaration && signature.declaration.flags & NodeFlags.Deprecated) { + errorOrSuggestion(/*isError*/ false, node, Diagnostics._0_is_deprecated, signatureToString(signature)); + } + } + function isSymbolOrSymbolForCall(node: Node) { if (!isCallExpression(node)) return false; let left = node.expression; @@ -27571,7 +27648,9 @@ namespace ts { if (languageVersion < ScriptTarget.ES2015) { checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject); } - return getReturnTypeOfSignature(getResolvedSignature(node)); + const signature = getResolvedSignature(node); + checkDeprecatedSignature(signature, node); + return getReturnTypeOfSignature(signature); } function checkAssertion(node: AssertionExpression) { @@ -27698,13 +27777,13 @@ namespace ts { return d.name.escapedText; } - function getParameterNameAtPosition(signature: Signature, pos: number) { + function getParameterNameAtPosition(signature: Signature, pos: number, overrideRestType?: Type) { const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); if (pos < paramCount) { return signature.parameters[pos].escapedName; } const restParameter = signature.parameters[paramCount] || unknownSymbol; - const restType = getTypeOfSymbol(restParameter); + const restType = overrideRestType || getTypeOfSymbol(restParameter); if (isTupleType(restType)) { const associatedNames = ((restType).target).labeledElementDeclarations; const index = pos - paramCount; @@ -28507,7 +28586,7 @@ namespace ts { expr.expression.kind === SyntaxKind.ThisKeyword) { // Look for if this is the constructor for the class that `symbol` is a property of. const ctor = getContainingFunction(expr); - if (!(ctor && ctor.kind === SyntaxKind.Constructor)) { + if (!(ctor && (ctor.kind === SyntaxKind.Constructor || isJSConstructor(ctor)))) { return true; } if (symbol.valueDeclaration) { @@ -29478,8 +29557,8 @@ namespace ts { case AssignmentDeclarationKind.ThisProperty: const symbol = getSymbolOfNode(left); const init = getAssignedExpandoInitializer(right); - return init && isObjectLiteralExpression(init) && - symbol && hasEntries(symbol.exports); + return !!init && isObjectLiteralExpression(init) && + !!symbol?.exports?.size; default: return false; } @@ -30438,10 +30517,10 @@ namespace ts { } function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) { - const instanceNames = createUnderscoreEscapedMap(); - const staticNames = createUnderscoreEscapedMap(); + const instanceNames = new Map<__String, DeclarationMeaning>(); + const staticNames = new Map<__String, DeclarationMeaning>(); // instance and static private identifiers share the same scope - const privateIdentifiers = createUnderscoreEscapedMap(); + const privateIdentifiers = new Map<__String, DeclarationMeaning>(); for (const member of node.members) { if (member.kind === SyntaxKind.Constructor) { for (const param of (member as ConstructorDeclaration).parameters) { @@ -30537,7 +30616,7 @@ namespace ts { } function checkObjectTypeForDuplicateDeclarations(node: TypeLiteralNode | InterfaceDeclaration) { - const names = createMap(); + const names = new Map(); for (const member of node.members) { if (member.kind === SyntaxKind.PropertySignature) { let memberName: string; @@ -30847,7 +30926,7 @@ namespace ts { } const symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { - if (symbol.flags & SymbolFlags.Deprecated) { + if (some(symbol.declarations, d => isTypeDeclaration(d) && !!(d.flags & NodeFlags.Deprecated))) { const diagLocation = isTypeReferenceNode(node) && isQualifiedName(node.typeName) ? node.typeName.right : node; errorOrSuggestion(/* isError */ false, diagLocation, Diagnostics._0_is_deprecated, symbol.escapedName as string); } @@ -31699,6 +31778,7 @@ namespace ts { /** Check a decorator */ function checkDecorator(node: Decorator): void { const signature = getResolvedSignature(node); + checkDeprecatedSignature(signature, node); const returnType = getReturnTypeOfSignature(signature); if (returnType.flags & TypeFlags.Any) { return; @@ -32234,7 +32314,7 @@ namespace ts { if (last(getSymbolOfNode(node).declarations) !== node) return; const typeParameters = getEffectiveTypeParameterDeclarations(node); - const seenParentsWithEveryUnused = new NodeSet(); + const seenParentsWithEveryUnused = new Set(); for (const typeParameter of typeParameters) { if (!isTypeParameterUnused(typeParameter)) continue; @@ -32242,7 +32322,7 @@ namespace ts { const name = idText(typeParameter.name); const { parent } = typeParameter; if (parent.kind !== SyntaxKind.InferType && parent.typeParameters!.every(isTypeParameterUnused)) { - if (seenParentsWithEveryUnused.tryAdd(parent)) { + if (tryAddToSet(seenParentsWithEveryUnused, parent)) { const range = isJSDocTemplateTag(parent) // Whole @template tag ? rangeOfNode(parent) @@ -32263,7 +32343,7 @@ namespace ts { return !(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name); } - function addToGroup(map: Map, key: K, value: V, getKey: (key: K) => number | string): void { + function addToGroup(map: ESMap, key: K, value: V, getKey: (key: K) => number | string): void { const keyString = String(getKey(key)); const group = map.get(keyString); if (group) { @@ -32292,9 +32372,9 @@ namespace ts { function checkUnusedLocalsAndParameters(nodeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void { // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value. - const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>(); - const unusedDestructures = createMap<[ObjectBindingPattern, BindingElement[]]>(); - const unusedVariables = createMap<[VariableDeclarationList, VariableDeclaration[]]>(); + const unusedImports = new Map(); + const unusedDestructures = new Map(); + const unusedVariables = new Map(); nodeWithLocals.locals!.forEach(local => { // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`. // If it's a type parameter merged with a parameter, check if the parameter-side is used. @@ -32721,7 +32801,7 @@ namespace ts { const isJSObjectLiteralInitializer = isInJSFile(node) && isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAccess(node.name)) && - hasEntries(symbol.exports); + !!symbol.exports?.size; if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined); } @@ -34545,7 +34625,7 @@ namespace ts { if (!length(baseTypes)) { return properties; } - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, Symbol>(); forEach(properties, p => { seen.set(p.escapedName, p); }); for (const base of baseTypes) { @@ -34568,7 +34648,7 @@ namespace ts { } interface InheritanceInfoMap { prop: Symbol; containingType: Type; } - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, InheritanceInfoMap>(); forEach(resolveDeclaredMembers(type).declaredProperties, p => { seen.set(p.escapedName, { prop: p, containingType: type }); }); let ok = true; @@ -35162,37 +35242,36 @@ namespace ts { const target = resolveAlias(symbol); if (target !== unknownSymbol) { - const shouldSkipWithJSExpandoTargets = symbol.flags & SymbolFlags.Assignment; - if (!shouldSkipWithJSExpandoTargets) { - // For external modules symbol represents local symbol for an alias. - // This local symbol will merge any other local declarations (excluding other aliases) - // and symbol.flags will contains combined representation for all merged declaration. - // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have, - // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* - // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). - symbol = getMergedSymbol(symbol.exportSymbol || symbol); - const excludedMeanings = - (symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) | - (symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) | - (symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0); - if (target.flags & excludedMeanings) { - const message = node.kind === SyntaxKind.ExportSpecifier ? - Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 : - Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; - error(node, message, symbolToString(symbol)); - } - - // Don't allow to re-export something with no value side when `--isolatedModules` is set. - if (compilerOptions.isolatedModules - && node.kind === SyntaxKind.ExportSpecifier - && !node.parent.parent.isTypeOnly - && !(target.flags & SymbolFlags.Value) - && !(node.flags & NodeFlags.Ambient)) { - error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type); - } - } - - if (isImportSpecifier(node) && target.flags & SymbolFlags.Deprecated) { + // For external modules, `symbol` represents the local symbol for an alias. + // This local symbol will merge any other local declarations (excluding other aliases) + // and symbol.flags will contains combined representation for all merged declaration. + // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have, + // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* + // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). + symbol = getMergedSymbol(symbol.exportSymbol || symbol); + const excludedMeanings = + (symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) | + (symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) | + (symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0); + if (target.flags & excludedMeanings) { + const message = node.kind === SyntaxKind.ExportSpecifier ? + Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 : + Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; + error(node, message, symbolToString(symbol)); + } + + // Don't allow to re-export something with no value side when `--isolatedModules` is set. + if (compilerOptions.isolatedModules + && node.kind === SyntaxKind.ExportSpecifier + && !node.parent.parent.isTypeOnly + && !(target.flags & SymbolFlags.Value) + && !(node.flags & NodeFlags.Ambient)) { + error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type); + } + + if (isImportSpecifier(node) && + (target.valueDeclaration && target.valueDeclaration.flags & NodeFlags.Deprecated + || every(target.declarations, d => !!(d.flags & NodeFlags.Deprecated)))) { errorOrSuggestion(/* isError */ false, node.name, Diagnostics._0_is_deprecated, symbol.escapedName as string); } } @@ -35202,6 +35281,12 @@ namespace ts { checkCollisionWithRequireExportsInGeneratedCode(node, node.name!); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name!); checkAliasSymbol(node); + if (node.kind === SyntaxKind.ImportSpecifier && + idText(node.propertyName || node.name) === "default" && + compilerOptions.esModuleInterop && + moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); + } } function checkImportDeclaration(node: ImportDeclaration) { @@ -35221,6 +35306,10 @@ namespace ts { if (importClause.namedBindings) { if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { checkImportBinding(importClause.namedBindings); + if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015 && compilerOptions.esModuleInterop) { + // import * as ns from "foo"; + checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); + } } else { const moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier); @@ -35231,6 +35320,7 @@ namespace ts { } } } + } function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { @@ -35298,6 +35388,7 @@ namespace ts { } else { // export * from "foo" + // export * as ns from "foo"; const moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier!); if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) { error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); @@ -35306,7 +35397,18 @@ namespace ts { checkAliasSymbol(node.exportClause); } if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); + if (node.exportClause) { + // export * as ns from "foo"; + // For ES2015 modules, we emit it as a pair of `import * as a_1 ...; export { a_1 as ns }` and don't need the helper. + // We only use the helper here when in esModuleInterop + if (compilerOptions.esModuleInterop) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); + } + } + else { + // export * from "foo" + checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); + } } } } @@ -35378,6 +35480,14 @@ namespace ts { } } } + else { + if (compilerOptions.esModuleInterop && + moduleKind !== ModuleKind.System && + moduleKind < ModuleKind.ES2015 && + idText(node.propertyName || node.name) === "default") { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); + } + } } function checkExportAssignment(node: ExportAssignment) { @@ -35758,8 +35868,8 @@ namespace ts { const enclosingFile = getSourceFileOfNode(node); const links = getNodeLinks(enclosingFile); if (!(links.flags & NodeCheckFlags.TypeChecked)) { - links.deferredNodes = links.deferredNodes || createMap(); - const id = "" + getNodeId(node); + links.deferredNodes = links.deferredNodes || new Map(); + const id = getNodeId(node); links.deferredNodes.set(id, node); } } @@ -36055,16 +36165,19 @@ namespace ts { function isTypeDeclarationName(name: Node): boolean { return name.kind === SyntaxKind.Identifier && isTypeDeclaration(name.parent) && - name.parent.name === name; + getNameOfDeclaration(name.parent) === name; } - function isTypeDeclaration(node: Node): node is TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration | ImportClause | ImportSpecifier | ExportSpecifier { + function isTypeDeclaration(node: Node): node is TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | EnumDeclaration | ImportClause | ImportSpecifier | ExportSpecifier { switch (node.kind) { case SyntaxKind.TypeParameter: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.EnumDeclaration: + case SyntaxKind.JSDocTypedefTag: + case SyntaxKind.JSDocCallbackTag: + case SyntaxKind.JSDocEnumTag: return true; case SyntaxKind.ImportClause: return (node as ImportClause).isTypeOnly; @@ -36897,6 +37010,12 @@ namespace ts { hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); } + function isOptionalUninitializedParameter(parameter: ParameterDeclaration) { + return !!strictNullChecks && + isOptionalParameter(parameter) && + !parameter.initializer; + } + function isExpandoFunctionDeclaration(node: Declaration): boolean { const declaration = getParseTreeNode(node, isFunctionDeclaration); if (!declaration) { @@ -36969,29 +37088,31 @@ namespace ts { } // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. - const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); + const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location); + const isTypeOnly = valueSymbol?.declarations?.every(isTypeOnlyImportOrExportDeclaration) || false; + const resolvedSymbol = valueSymbol && valueSymbol.flags & SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol; // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); - if (valueSymbol && valueSymbol === typeSymbol) { + if (resolvedSymbol && resolvedSymbol === typeSymbol) { const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); - if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { + if (globalPromiseSymbol && resolvedSymbol === globalPromiseSymbol) { return TypeReferenceSerializationKind.Promise; } - const constructorType = getTypeOfSymbol(valueSymbol); + const constructorType = getTypeOfSymbol(resolvedSymbol); if (constructorType && isConstructorType(constructorType)) { - return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; + return isTypeOnly ? TypeReferenceSerializationKind.TypeWithCallSignature : TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } } // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { - return TypeReferenceSerializationKind.Unknown; + return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; } const type = getDeclaredTypeOfSymbol(typeSymbol); if (type === errorType) { - return TypeReferenceSerializationKind.Unknown; + return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; } else if (type.flags & TypeFlags.AnyOrUnknown) { return TypeReferenceSerializationKind.ObjectType; @@ -37154,10 +37275,10 @@ namespace ts { // this variable and functions that use it are deliberately moved here from the outer scope // to avoid scope pollution const resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives(); - let fileToDirective: Map; + let fileToDirective: ESMap; if (resolvedTypeReferenceDirectives) { // populate reverse mapping: file path -> type reference directive that was resolved to this file - fileToDirective = createMap(); + fileToDirective = new Map(); resolvedTypeReferenceDirectives.forEach((resolvedDirective, key) => { if (!resolvedDirective || !resolvedDirective.resolvedFileName) { return; @@ -37366,7 +37487,7 @@ namespace ts { if (fileToDirective.has(file.path)) return; fileToDirective.set(file.path, key); for (const { fileName } of file.referencedFiles) { - const resolvedFile = resolveTripleslashReference(fileName, file.originalFileName); + const resolvedFile = resolveTripleslashReference(fileName, file.fileName); const referencedFile = host.getSourceFile(resolvedFile); if (referencedFile) { addReferencedFilesToTypeDirective(referencedFile, key); @@ -37390,7 +37511,7 @@ namespace ts { bindSourceFile(file, compilerOptions); } - amalgamatedDuplicates = createMap(); + amalgamatedDuplicates = new Map(); // Initialize global symbol table let augmentations: (readonly (StringLiteral | Identifier)[])[] | undefined; @@ -37557,6 +37678,8 @@ namespace ts { case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; case ExternalEmitHelpers.ExportStar: return "__exportStar"; + case ExternalEmitHelpers.ImportStar: return "__importStar"; + case ExternalEmitHelpers.ImportDefault: return "__importDefault"; case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; case ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet"; case ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet"; @@ -38196,7 +38319,7 @@ namespace ts { } function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) { - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, DeclarationMeaning>(); for (const prop of node.properties) { if (prop.kind === SyntaxKind.SpreadAssignment) { @@ -38218,7 +38341,7 @@ namespace ts { if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern // outside of destructuring it is a syntax error - return grammarErrorOnNode(prop.equalsToken!, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); + return grammarErrorOnNode(prop.equalsToken!, Diagnostics.Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern); } if (name.kind === SyntaxKind.PrivateIdentifier) { @@ -38301,7 +38424,7 @@ namespace ts { function checkGrammarJsxElement(node: JsxOpeningLikeElement) { checkGrammarTypeArguments(node, node.typeArguments); - const seen = createUnderscoreEscapedMap(); + const seen = new Map<__String, boolean>(); for (const attr of node.attributes.properties) { if (attr.kind === SyntaxKind.JsxSpreadAttribute) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b2884340dfce0..f5cb2990a593a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -83,33 +83,33 @@ namespace ts { export const optionsForWatch: CommandLineOption[] = [ { name: "watchFile", - type: createMapFromTemplate({ + type: new Map(getEntries({ fixedpollinginterval: WatchFileKind.FixedPollingInterval, prioritypollinginterval: WatchFileKind.PriorityPollingInterval, dynamicprioritypolling: WatchFileKind.DynamicPriorityPolling, usefsevents: WatchFileKind.UseFsEvents, usefseventsonparentdirectory: WatchFileKind.UseFsEventsOnParentDirectory, - }), + })), category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory, }, { name: "watchDirectory", - type: createMapFromTemplate({ + type: new Map(getEntries({ usefsevents: WatchDirectoryKind.UseFsEvents, fixedpollinginterval: WatchDirectoryKind.FixedPollingInterval, dynamicprioritypolling: WatchDirectoryKind.DynamicPriorityPolling, - }), + })), category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling, }, { name: "fallbackPolling", - type: createMapFromTemplate({ + type: new Map(getEntries({ fixedinterval: PollingWatchKind.FixedInterval, priorityinterval: PollingWatchKind.PriorityInterval, dynamicpriority: PollingWatchKind.DynamicPriority, - }), + })), category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority, }, @@ -286,7 +286,7 @@ namespace ts { { name: "target", shortName: "t", - type: createMapFromTemplate({ + type: new Map(getEntries({ es3: ScriptTarget.ES3, es5: ScriptTarget.ES5, es6: ScriptTarget.ES2015, @@ -297,7 +297,7 @@ namespace ts { es2019: ScriptTarget.ES2019, es2020: ScriptTarget.ES2020, esnext: ScriptTarget.ESNext, - }), + })), affectsSourceFile: true, affectsModuleResolution: true, affectsEmit: true, @@ -309,7 +309,7 @@ namespace ts { { name: "module", shortName: "m", - type: createMapFromTemplate({ + type: new Map(getEntries({ none: ModuleKind.None, commonjs: ModuleKind.CommonJS, amd: ModuleKind.AMD, @@ -319,7 +319,7 @@ namespace ts { es2015: ModuleKind.ES2015, es2020: ModuleKind.ES2020, esnext: ModuleKind.ESNext - }), + })), affectsModuleResolution: true, affectsEmit: true, paramType: Diagnostics.KIND, @@ -356,11 +356,11 @@ namespace ts { }, { name: "jsx", - type: createMapFromTemplate({ + type: new Map(getEntries({ "preserve": JsxEmit.Preserve, "react-native": JsxEmit.ReactNative, "react": JsxEmit.React - }), + })), affectsSourceFile: true, paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, @@ -476,11 +476,11 @@ namespace ts { }, { name: "importsNotUsedAsValues", - type: createMapFromTemplate({ + type: new Map(getEntries({ remove: ImportsNotUsedAsValues.Remove, preserve: ImportsNotUsedAsValues.Preserve, error: ImportsNotUsedAsValues.Error - }), + })), affectsEmit: true, affectsSemanticDiagnostics: true, category: Diagnostics.Advanced_Options, @@ -610,10 +610,10 @@ namespace ts { // Module Resolution { name: "moduleResolution", - type: createMapFromTemplate({ + type: new Map(getEntries({ node: ModuleResolutionKind.NodeJs, classic: ModuleResolutionKind.Classic, - }), + })), affectsModuleResolution: true, paramType: Diagnostics.STRATEGY, category: Diagnostics.Module_Resolution_Options, @@ -818,10 +818,10 @@ namespace ts { }, { name: "newLine", - type: createMapFromTemplate({ + type: new Map(getEntries({ crlf: NewLineKind.CarriageReturnLineFeed, lf: NewLineKind.LineFeed - }), + })), affectsEmit: true, paramType: Diagnostics.NEWLINE, category: Diagnostics.Advanced_Options, @@ -1090,14 +1090,14 @@ namespace ts { /* @internal */ export interface OptionsNameMap { - optionsNameMap: Map; - shortOptionNames: Map; + optionsNameMap: ESMap; + shortOptionNames: ESMap; } /*@internal*/ export function createOptionNameMap(optionDeclarations: readonly CommandLineOption[]): OptionsNameMap { - const optionsNameMap = createMap(); - const shortOptionNames = createMap(); + const optionsNameMap = new Map(); + const shortOptionNames = new Map(); forEach(optionDeclarations, option => { optionsNameMap.set(option.name.toLowerCase(), option); if (option.shortName) { @@ -1469,7 +1469,7 @@ namespace ts { configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost, - extendedConfigCache?: Map, + extendedConfigCache?: Map, watchOptionsToExtend?: WatchOptions, extraFileExtensions?: readonly FileExtensionInfo[], ): ParsedCommandLine | undefined { @@ -1562,15 +1562,15 @@ namespace ts { optionTypeMismatchDiagnostic: Diagnostics.Watch_option_0_requires_a_value_of_type_1 }; - let commandLineCompilerOptionsMapCache: Map; + let commandLineCompilerOptionsMapCache: ESMap; function getCommandLineCompilerOptionsMap() { return commandLineCompilerOptionsMapCache || (commandLineCompilerOptionsMapCache = commandLineOptionsToMap(optionDeclarations)); } - let commandLineWatchOptionsMapCache: Map; + let commandLineWatchOptionsMapCache: ESMap; function getCommandLineWatchOptionsMap() { return commandLineWatchOptionsMapCache || (commandLineWatchOptionsMapCache = commandLineOptionsToMap(optionsForWatch)); } - let commandLineTypeAcquisitionMapCache: Map; + let commandLineTypeAcquisitionMapCache: ESMap; function getCommandLineTypeAcquisitionMap() { return commandLineTypeAcquisitionMapCache || (commandLineTypeAcquisitionMapCache = commandLineOptionsToMap(typeAcquisitionDeclarations)); } @@ -1703,13 +1703,13 @@ namespace ts { return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions); - function isRootOptionMap(knownOptions: Map | undefined) { + function isRootOptionMap(knownOptions: ESMap | undefined) { return knownRootOptions && (knownRootOptions as TsConfigOnlyOption).elementOptions === knownOptions; } function convertObjectLiteralExpressionToJson( node: ObjectLiteralExpression, - knownOptions: Map | undefined, + knownOptions: ESMap | undefined, extraKeyDiagnostics: DidYouMeanOptionsDiagnostics | undefined, parentOption: string | undefined ): any { @@ -1964,7 +1964,7 @@ namespace ts { return config; } - function optionMapToObject(optionMap: Map): object { + function optionMapToObject(optionMap: ESMap): object { return { ...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}), }; @@ -1994,7 +1994,7 @@ namespace ts { return _ => true; } - function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map | undefined { + function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): ESMap | undefined { if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") { // this is of a type CommandLineOptionOfPrimitiveType return undefined; @@ -2007,7 +2007,7 @@ namespace ts { } } - function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map): string | undefined { + function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: ESMap): string | undefined { // There is a typeMap associated with this command-line option so use it to map value back to its name return forEachEntry(customTypeMap, (mapValue, key) => { if (mapValue === value) { @@ -2019,7 +2019,7 @@ namespace ts { function serializeCompilerOptions( options: CompilerOptions, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean } - ): Map { + ): ESMap { return serializeOptionBaseObject(options, getOptionsNameMap(), pathOptions); } @@ -2031,8 +2031,8 @@ namespace ts { options: OptionsBase, { optionsNameMap }: OptionsNameMap, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean } - ): Map { - const result = createMap(); + ): ESMap { + const result = new Map(); const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames); for (const name in options) { @@ -2220,7 +2220,7 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { + export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache); } @@ -2231,7 +2231,7 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { + export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: readonly FileExtensionInfo[], extendedConfigCache?: Map, existingWatchOptions?: WatchOptions): ParsedCommandLine { return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache); } @@ -2271,7 +2271,7 @@ namespace ts { configFileName?: string, resolutionStack: Path[] = [], extraFileExtensions: readonly FileExtensionInfo[] = [], - extendedConfigCache?: Map + extendedConfigCache?: ESMap ): ParsedCommandLine { Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined)); const errors: Diagnostic[] = []; @@ -2456,7 +2456,7 @@ namespace ts { configFileName: string | undefined, resolutionStack: string[], errors: Push, - extendedConfigCache?: Map + extendedConfigCache?: ESMap ): ParsedTsconfig { basePath = normalizeSlashes(basePath); const resolvedPath = getNormalizedAbsolutePath(configFileName || "", basePath); @@ -2645,7 +2645,7 @@ namespace ts { basePath: string, resolutionStack: string[], errors: Push, - extendedConfigCache?: Map + extendedConfigCache?: ESMap ): ParsedTsconfig | undefined { const path = host.useCaseSensitiveFileNames ? extendedConfigPath : toFileNameLowerCase(extendedConfigPath); let value: ExtendedConfigCacheEntry | undefined; @@ -2750,11 +2750,11 @@ namespace ts { return convertOptionsFromJson(getCommandLineWatchOptionsMap(), jsonOptions, basePath, /*defaultOptions*/ undefined, watchOptionsDidYouMeanDiagnostics, errors); } - function convertOptionsFromJson(optionsNameMap: Map, jsonOptions: any, basePath: string, + function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, defaultOptions: undefined, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push): WatchOptions | undefined; - function convertOptionsFromJson(optionsNameMap: Map, jsonOptions: any, basePath: string, + function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, defaultOptions: CompilerOptions | TypeAcquisition, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push): CompilerOptions | TypeAcquisition; - function convertOptionsFromJson(optionsNameMap: Map, jsonOptions: any, basePath: string, + function convertOptionsFromJson(optionsNameMap: ESMap, jsonOptions: any, basePath: string, defaultOptions: CompilerOptions | TypeAcquisition | WatchOptions | undefined, diagnostics: DidYouMeanOptionsDiagnostics, errors: Push) { if (!jsonOptions) { @@ -2962,17 +2962,17 @@ namespace ts { // Literal file names (provided via the "files" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map later when when including // wildcard paths. - const literalFileMap = createMap(); + const literalFileMap = new Map(); // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard, and to handle extension priority. - const wildcardFileMap = createMap(); + const wildcardFileMap = new Map(); // Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard of *.json kind - const wildCardJsonFileMap = createMap(); + const wildCardJsonFileMap = new Map(); const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec; // Rather than requery this for each file and filespec, we query the supported extensions @@ -3174,7 +3174,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map, wildcardFiles: Map, extensions: readonly string[], keyMapper: (value: string) => string) { + function hasFileWithHigherPriorityExtension(file: string, literalFiles: ESMap, wildcardFiles: ESMap, extensions: readonly string[], keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority, extensions); for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) { @@ -3196,7 +3196,7 @@ namespace ts { * @param extensionPriority The priority of the extension. * @param context The expansion context. */ - function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map, extensions: readonly string[], keyMapper: (value: string) => string) { + function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: ESMap, extensions: readonly string[], keyMapper: (value: string) => string) { const extensionPriority = getExtensionPriority(file, extensions); const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority, extensions); for (let i = nextExtensionPriority; i < extensions.length; i++) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 573a45b9f3b1d..753af89b59015 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,7 +1,7 @@ /* @internal */ namespace ts { - type GetIteratorCallback = | ReadonlyMap | undefined>(iterable: I) => Iterator< - I extends ReadonlyMap ? [K, V] : + type GetIteratorCallback = | ReadonlyESMap | undefined>(iterable: I) => Iterator< + I extends ReadonlyESMap ? [K, V] : I extends ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : @@ -20,17 +20,17 @@ namespace ts { export const Map = getCollectionImplementation("Map", "tryGetNativeMap", "createMapShim"); export const Set = getCollectionImplementation("Set", "tryGetNativeSet", "createSetShim"); - export function getIterator | ReadonlyMap | undefined>(iterable: I): Iterator< - I extends ReadonlyMap ? [K, V] : + export function getIterator | ReadonlyESMap | undefined>(iterable: I): Iterator< + I extends ReadonlyESMap ? [K, V] : I extends ReadonlySet ? T : I extends readonly (infer T)[] ? T : I extends undefined ? undefined : never>; - export function getIterator(iterable: ReadonlyMap): Iterator<[K, V]>; - export function getIterator(iterable: ReadonlyMap | undefined): Iterator<[K, V]> | undefined; + export function getIterator(iterable: ReadonlyESMap): Iterator<[K, V]>; + export function getIterator(iterable: ReadonlyESMap | undefined): Iterator<[K, V]> | undefined; export function getIterator(iterable: readonly T[] | ReadonlySet): Iterator; export function getIterator(iterable: readonly T[] | ReadonlySet | undefined): Iterator | undefined; - export function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyMap | undefined): Iterator | undefined { + export function getIterator(iterable: readonly any[] | ReadonlySet | ReadonlyESMap | undefined): Iterator | undefined { if (iterable) { if (isArray(iterable)) return arrayIterator(iterable); if (iterable instanceof Map) return iterable.entries(); @@ -40,17 +40,25 @@ namespace ts { } export const emptyArray: never[] = [] as never[]; + export const emptyMap: ReadonlyESMap = new Map(); + export const emptySet: ReadonlySet = new Set(); - /** Create a new map. */ - export function createMap(): Map; - export function createMap(): Map; - export function createMap(): Map { + /** + * Create a new map. + * @deprecated Use `new Map()` instead. + */ + export function createMap(): ESMap; + export function createMap(): ESMap; + export function createMap(): ESMap { return new Map(); } - /** Create a new map from a template object is provided, the map will copy entries from it. */ - export function createMapFromTemplate(template: MapLike): Map { - const map: Map = new Map(); + /** + * Create a new map from a template object is provided, the map will copy entries from it. + * @deprecated Use `new Map(getEntries(template))` instead. + */ + export function createMapFromTemplate(template: MapLike): ESMap { + const map: ESMap = new Map(); // Copies keys/values from template. Note that for..in will not throw if // template is undefined, and instead will just exit the loop. @@ -160,7 +168,7 @@ namespace ts { }; } - export function zipToMap(keys: readonly K[], values: readonly V[]): Map { + export function zipToMap(keys: readonly K[], values: readonly V[]): ESMap { Debug.assert(keys.length === values.length); const map = new Map(); for (let i = 0; i < keys.length; ++i) { @@ -554,9 +562,9 @@ namespace ts { }; } - export function mapDefinedEntries(map: ReadonlyMap, f: (key: K1, value: V1) => readonly [K2, V2] | undefined): Map; - export function mapDefinedEntries(map: ReadonlyMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): Map | undefined; - export function mapDefinedEntries(map: ReadonlyMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): Map | undefined { + export function mapDefinedEntries(map: ReadonlyESMap, f: (key: K1, value: V1) => readonly [K2, V2] | undefined): ESMap; + export function mapDefinedEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): ESMap | undefined; + export function mapDefinedEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): ESMap | undefined { if (!map) { return undefined; } @@ -590,6 +598,15 @@ namespace ts { } } + export function getOrUpdate(map: ESMap, key: K, callback: () => V) { + if (map.has(key)) { + return map.get(key)!; + } + const value = callback(); + map.set(key, value); + return value; + } + export function tryAddToSet(set: Set, value: T) { if (!set.has(value)) { set.add(value); @@ -660,9 +677,9 @@ namespace ts { return result; } - export function mapEntries(map: ReadonlyMap, f: (key: K1, value: V1) => readonly [K2, V2]): Map; - export function mapEntries(map: ReadonlyMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): Map | undefined; - export function mapEntries(map: ReadonlyMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): Map | undefined { + export function mapEntries(map: ReadonlyESMap, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap; + export function mapEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap | undefined; + export function mapEntries(map: ReadonlyESMap | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): ESMap | undefined { if (!map) { return undefined; } @@ -819,6 +836,18 @@ namespace ts { return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer); } + export function arrayIsSorted(array: readonly T[], comparer: Comparer) { + if (array.length < 2) return true; + let prevElement = array[0]; + for (const element of array.slice(1)) { + if (comparer(prevElement, element) === Comparison.GreaterThan) { + return false; + } + prevElement = element; + } + return true; + } + export function arrayIsEqualTo(array1: readonly T[] | undefined, array2: readonly T[] | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean { if (!array1 || !array2) { return array1 === array2; @@ -1275,6 +1304,19 @@ namespace ts { return values; } + const _entries = Object.entries ? Object.entries : (obj: MapLike) => { + const keys = getOwnKeys(obj); + const result: [string, T][] = Array(keys.length); + for (const key of keys) { + result.push([key, obj[key]]); + } + return result; + }; + + export function getEntries(obj: MapLike): [string, T][] { + return obj ? _entries(obj) : []; + } + export function arrayOf(count: number, f: (index: number) => T): T[] { const result = new Array(count); for (let i = 0; i < count; i++) { @@ -1342,11 +1384,11 @@ namespace ts { * the same key with the given 'makeKey' function, then the element with the higher * index in the array will be the one associated with the produced key. */ - export function arrayToMap(array: readonly V[], makeKey: (value: V) => K | undefined): Map; - export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V2): Map; - export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined): Map; - export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined, makeValue: (value: T) => U): Map; - export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V1 | V2 = identity): Map { + export function arrayToMap(array: readonly V[], makeKey: (value: V) => K | undefined): ESMap; + export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V2): ESMap; + export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined): ESMap; + export function arrayToMap(array: readonly T[], makeKey: (value: T) => string | undefined, makeValue: (value: T) => U): ESMap; + export function arrayToMap(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V1 | V2 = identity): ESMap { const result = new Map(); for (const value of array) { const key = makeKey(value); @@ -1375,9 +1417,11 @@ namespace ts { return result; } + export function group(values: readonly T[], getGroupId: (value: T) => K): readonly (readonly T[])[]; + export function group(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => R): R[]; export function group(values: readonly T[], getGroupId: (value: T) => string): readonly (readonly T[])[]; export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => R): R[]; - export function group(values: readonly T[], getGroupId: (value: T) => string, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] { + export function group(values: readonly T[], getGroupId: (value: T) => K, resultSelector: (values: readonly T[]) => readonly T[] = identity): readonly (readonly T[])[] { return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector); } @@ -1425,7 +1469,7 @@ namespace ts { return fn ? fn.bind(obj) : undefined; } - export interface MultiMap extends Map { + export interface MultiMap extends ESMap { /** * Adds the value to an array of values associated with the key, and returns the array. * Creates the array if it does not already exist. @@ -1596,7 +1640,7 @@ namespace ts { /** A version of `memoize` that supports a single primitive argument */ export function memoizeOne(callback: (arg: A) => T): (arg: A) => T { - const map = createMap(); + const map = new Map(); return (arg: A) => { const key = `${typeof arg}:${arg}`; let value = map.get(key); diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index f580dc5b92451..dad59377900e1 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -36,22 +36,34 @@ namespace ts { } /** ES6 Map interface, only read methods included. */ - export interface ReadonlyMap extends ReadonlyCollection { + export interface ReadonlyESMap extends ReadonlyCollection { get(key: K): V | undefined; values(): Iterator; entries(): Iterator<[K, V]>; forEach(action: (value: V, key: K) => void): void; } + /** + * ES6 Map interface, only read methods included. + */ + export interface ReadonlyMap extends ReadonlyESMap { + } + /** ES6 Map interface. */ - export interface Map extends ReadonlyMap, Collection { + export interface ESMap extends ReadonlyESMap, Collection { set(key: K, value: V): this; } + /** + * ES6 Map interface. + */ + export interface Map extends ESMap { + } + /* @internal */ export interface MapConstructor { // eslint-disable-next-line @typescript-eslint/prefer-function-type - new (iterable?: readonly (readonly [K, V])[] | ReadonlyMap): Map; + new (iterable?: readonly (readonly [K, V])[] | ReadonlyESMap): ESMap; } /** ES6 Set interface, only read methods included. */ diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b32e8d020290b..5110ff2be8b72 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -880,7 +880,7 @@ "category": "Error", "code": 1308 }, - "'=' can only be used in an object literal property inside a destructuring assignment.": { + "Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern.": { "category": "Error", "code": 1312 }, @@ -1164,6 +1164,22 @@ "category": "Error", "code": 1384 }, + "Function type notation must be parenthesized when used in a union type.": { + "category": "Error", + "code": 1385 + }, + "Constructor type notation must be parenthesized when used in a union type.": { + "category": "Error", + "code": 1386 + }, + "Function type notation must be parenthesized when used in an intersection type.": { + "category": "Error", + "code": 1387 + }, + "Constructor type notation must be parenthesized when used in an intersection type.": { + "category": "Error", + "code": 1388 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", @@ -3041,6 +3057,10 @@ "category": "Error", "code": 4020 }, + "'extends' clause of exported class has or is using private name '{0}'.": { + "category": "Error", + "code": 4021 + }, "'extends' clause of exported interface '{0}' has or is using private name '{1}'.": { "category": "Error", "code": 4022 @@ -5155,10 +5175,6 @@ "category": "Message", "code": 90008 }, - "Remove destructuring": { - "category": "Message", - "code": 90009 - }, "Remove variable statement": { "category": "Message", "code": 90010 @@ -5275,6 +5291,14 @@ "category": "Message", "code": 90038 }, + "Remove unused destructuring declaration": { + "category": "Message", + "code": 90039 + }, + "Remove unused declarations for: '{0}'": { + "category": "Message", + "code": 90041 + }, "Declare a private field named '{0}'.": { "category": "Message", "code": 90053 @@ -5819,6 +5843,26 @@ "category": "Message", "code": 95137 }, + "Switch each misused '{0}' to '{1}'": { + "category": "Message", + "code": 95138 + }, + "Convert to optional chain expression": { + "category": "Message", + "code": 95139 + }, + "Could not find convertible access expression": { + "category": "Message", + "code": 95140 + }, + "Could not find matching access expressions": { + "category": "Message", + "code": 95141 + }, + "Can only convert logical AND access chains": { + "category": "Message", + "code": 95142 + }, "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8fec41fba5fce..2040a4af64246 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -682,9 +682,9 @@ namespace ts { function createSourceFilesFromBundleBuildInfo(bundle: BundleBuildInfo, buildInfoDirectory: string, host: EmitUsingBuildInfoHost): readonly SourceFile[] { const jsBundle = Debug.checkDefined(bundle.js); - const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => "" + prologueInfo.file); + const prologueMap = jsBundle.sources?.prologues && arrayToMap(jsBundle.sources.prologues, prologueInfo => prologueInfo.file); return bundle.sourceFiles.map((fileName, index) => { - const prologueInfo = prologueMap?.get("" + index); + const prologueInfo = prologueMap?.get(index); const statements = prologueInfo?.directives.map(directive => { const literal = setTextRange(factory.createStringLiteral(directive.expression.text), directive.expression); const statement = setTextRange(factory.createExpressionStatement(literal), directive); @@ -834,7 +834,7 @@ namespace ts { const extendedDiagnostics = !!printerOptions.extendedDiagnostics; const newLine = getNewLineCharacter(printerOptions); const moduleKind = getEmitModuleKind(printerOptions); - const bundledHelpers = createMap(); + const bundledHelpers = new Map(); let currentSourceFile: SourceFile | undefined; let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes. @@ -1682,7 +1682,7 @@ namespace ts { if (moduleKind === ModuleKind.None || printerOptions.noEmitHelpers) { return undefined; } - const bundledHelpers = createMap(); + const bundledHelpers = new Map(); for (const sourceFile of bundle.sourceFiles) { const shouldSkip = getExternalHelpersModuleName(sourceFile) !== undefined; const helpers = getSortedEmitHelpers(sourceFile); diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index e59c06f151647..15f86bf5a43fa 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -31,6 +31,7 @@ namespace ts { createImportStarHelper(expression: Expression): Expression; createImportStarCallbackHelper(): Expression; createImportDefaultHelper(expression: Expression): Expression; + createExportStarHelper(moduleExpression: Expression, exportsExpression?: Expression): Expression; // Class Fields Helpers createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier): Expression; createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression): Expression; @@ -69,6 +70,7 @@ namespace ts { createImportStarHelper, createImportStarCallbackHelper, createImportDefaultHelper, + createExportStarHelper, // Class Fields Helpers createClassPrivateFieldGetHelper, createClassPrivateFieldSetHelper, @@ -366,6 +368,16 @@ namespace ts { ); } + function createExportStarHelper(moduleExpression: Expression, exportsExpression: Expression = factory.createIdentifier("exports")) { + context.requestEmitHelper(exportStarHelper); + context.requestEmitHelper(createBindingHelper); + return factory.createCallExpression( + getUnscopedHelperName("__exportStar"), + /*typeArguments*/ undefined, + [moduleExpression, exportsExpression] + ); + } + // Class Fields Helpers function createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier) { @@ -568,7 +580,7 @@ namespace ts { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; @@ -798,7 +810,7 @@ namespace ts { var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; };` @@ -815,6 +827,19 @@ namespace ts { };` }; + // emit output for the __export helper function + export const exportStarHelper: UnscopedEmitHelper = { + name: "typescript:export-star", + importName: "__exportStar", + scoped: false, + dependencies: [createBindingHelper], + priority: 2, + text: ` + var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + };` + }; + // Class fields helpers export const classPrivateFieldGetHelper: UnscopedEmitHelper = { name: "typescript:classPrivateFieldGet", @@ -841,7 +866,7 @@ namespace ts { };` }; - let allUnscopedEmitHelpers: ReadonlyMap | undefined; + let allUnscopedEmitHelpers: ReadonlyESMap | undefined; export function getAllUnscopedEmitHelpers() { return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = arrayToMap([ @@ -864,6 +889,7 @@ namespace ts { generatorHelper, importStarHelper, importDefaultHelper, + exportStarHelper, classPrivateFieldGetHelper, classPrivateFieldSetHelper, createBindingHelper, diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index ef019d3df30d3..a9679f453fe43 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -5654,7 +5654,7 @@ namespace ts { left.splice(0, 0, ...declarations.slice(0, rightStandardPrologueEnd)); } else { - const leftPrologues = createMap(); + const leftPrologues = new Map(); for (let i = 0; i < leftStandardPrologueEnd; i++) { const leftPrologue = statements[i] as PrologueDirective; leftPrologues.set(leftPrologue.expression.text, true); @@ -6159,7 +6159,7 @@ namespace ts { ): InputFiles { const node = parseNodeFactory.createInputFiles(); if (!isString(javascriptTextOrReadFileText)) { - const cache = createMap(); + const cache = new Map(); const textGetter = (path: string | undefined) => { if (path === undefined) return undefined; let value = cache.get(path); diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 50d7e9a4d0f53..ad331c60be7f2 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -442,8 +442,8 @@ namespace ts { * This assumes that any module id will have the same resolution for sibling files located in the same folder. */ export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache { - getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; - /*@internal*/ directoryToModuleNameMap: CacheWithRedirects>; + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; + /*@internal*/ directoryToModuleNameMap: CacheWithRedirects>; } /** @@ -472,18 +472,18 @@ namespace ts { /*@internal*/ export interface CacheWithRedirects { - ownMap: Map; - redirectsMap: Map>; - getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map; + ownMap: ESMap; + redirectsMap: ESMap>; + getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): ESMap; clear(): void; setOwnOptions(newOptions: CompilerOptions): void; - setOwnMap(newOwnMap: Map): void; + setOwnMap(newOwnMap: ESMap): void; } /*@internal*/ export function createCacheWithRedirects(options?: CompilerOptions): CacheWithRedirects { - let ownMap: Map = createMap(); - const redirectsMap = new Map>(); + let ownMap: ESMap = new Map(); + const redirectsMap = new Map>(); return { ownMap, redirectsMap, @@ -497,7 +497,7 @@ namespace ts { options = newOptions; } - function setOwnMap(newOwnMap: Map) { + function setOwnMap(newOwnMap: ESMap) { ownMap = newOwnMap; } @@ -509,7 +509,7 @@ namespace ts { let redirects = redirectsMap.get(path); if (!redirects) { // Reuse map if redirected reference map uses same resolution - redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? createMap() : ownMap; + redirects = !options || optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? new Map() : ownMap; redirectsMap.set(path, redirects); } return redirects; @@ -523,7 +523,7 @@ namespace ts { /*@internal*/ export function createModuleResolutionCacheWithMaps( - directoryToModuleNameMap: CacheWithRedirects>, + directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap: CacheWithRedirects, currentDirectory: string, getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache { @@ -532,7 +532,7 @@ namespace ts { function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { const path = toPath(directoryName, currentDirectory, getCanonicalFileName); - return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, createMap); + return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => new Map()); } function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { @@ -551,7 +551,7 @@ namespace ts { } function createPerModuleNameCache(): PerModuleNameCache { - const directoryPathMap = createMap(); + const directoryPathMap = new Map(); return { get, set }; diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index b173bb1336453..96925b838e4ed 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -216,7 +216,7 @@ namespace ts.moduleSpecifiers { function getAllModulePaths(importingFileName: string, importedFileName: string, host: ModuleSpecifierResolutionHost): readonly string[] { const cwd = host.getCurrentDirectory(); const getCanonicalFileName = hostGetCanonicalFileName(host); - const allFileNames = createMap(); + const allFileNames = new Map(); let importedFileFromNodeModules = false; forEachFileNameOfModule( importingFileName, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2e8729b29c220..1729e3a810c4a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -722,8 +722,8 @@ namespace ts { let currentToken: SyntaxKind; let nodeCount: number; - let identifiers: Map; - let privateIdentifiers: Map; + let identifiers: ESMap; + let privateIdentifiers: ESMap; let identifierCount: number; let parsingContext: ParsingContext; @@ -820,7 +820,7 @@ namespace ts { result.libReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; result.hasNoDefaultLib = false; - result.pragmas = emptyMap; + result.pragmas = emptyMap as ReadonlyPragmaMap; return result; } @@ -929,8 +929,8 @@ namespace ts { parseDiagnostics = []; parsingContext = 0; - identifiers = createMap(); - privateIdentifiers = createMap(); + identifiers = new Map(); + privateIdentifiers = new Map(); identifierCount = 0; nodeCount = 0; sourceFlags = 0; @@ -2701,19 +2701,10 @@ namespace ts { return finishNode(factory.createThisTypeNode(), pos); } - function parseJSDocAllType(postFixEquals: boolean): JSDocAllType | JSDocOptionalType { + function parseJSDocAllType(): JSDocAllType | JSDocOptionalType { const pos = getNodePos(); nextToken(); - - const node = factory.createJSDocAllType(); - if (postFixEquals) { - // Trim the trailing `=` from the `*=` token - const end = Math.max(getNodePos() - 1, pos); - return finishNode(factory.createJSDocOptionalType(finishNode(node, pos, end)), pos); - } - else { - return finishNode(node, pos); - } + return finishNode(factory.createJSDocAllType(), pos); } function parseJSDocNonNullableType(): TypeNode { @@ -3396,12 +3387,14 @@ namespace ts { case SyntaxKind.ObjectKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. return tryParse(parseKeywordAndNoDot) || parseTypeReference(); - case SyntaxKind.AsteriskToken: - return parseJSDocAllType(/*postfixEquals*/ false); case SyntaxKind.AsteriskEqualsToken: - return parseJSDocAllType(/*postfixEquals*/ true); + // If there is '*=', treat it as * followed by postfix = + scanner.reScanAsteriskEqualsToken(); + // falls through + case SyntaxKind.AsteriskToken: + return parseJSDocAllType(); case SyntaxKind.QuestionQuestionToken: - // If there is '??', consider that is prefix '?' in JSDoc type. + // If there is '??', treat it as prefix-'?' in JSDoc type. scanner.reScanQuestionToken(); // falls through case SyntaxKind.QuestionToken: @@ -3576,18 +3569,46 @@ namespace ts { return parsePostfixTypeOrHigher(); } + function parseFunctionOrConstructorTypeToError( + isInUnionType: boolean + ): TypeNode | undefined { + // the function type and constructor type shorthand notation + // are not allowed directly in unions and intersections, but we'll + // try to parse them gracefully and issue a helpful message. + if (isStartOfFunctionTypeOrConstructorType()) { + const type = parseFunctionOrConstructorType(); + let diagnostic: DiagnosticMessage; + if (isFunctionTypeNode(type)) { + diagnostic = isInUnionType + ? Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type + : Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + } + else { + diagnostic = isInUnionType + ? Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type + : Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + + } + parseErrorAtRange(type, diagnostic); + return type; + } + return undefined; + } + function parseUnionOrIntersectionType( operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken, parseConstituentType: () => TypeNode, createTypeNode: (types: NodeArray) => UnionOrIntersectionTypeNode ): TypeNode { const pos = getNodePos(); + const isUnionType = operator === SyntaxKind.BarToken; const hasLeadingOperator = parseOptional(operator); - let type = parseConstituentType(); + let type = hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType) + || parseConstituentType(); if (token() === operator || hasLeadingOperator) { const types = [type]; while (parseOptional(operator)) { - types.push(parseConstituentType()); + types.push(parseFunctionOrConstructorTypeToError(isUnionType) || parseConstituentType()); } type = finishNode(createTypeNode(createNodeArray(types, pos)), pos); } @@ -3602,11 +3623,14 @@ namespace ts { return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); } - function isStartOfFunctionType(): boolean { + function isStartOfFunctionTypeOrConstructorType(): boolean { if (token() === SyntaxKind.LessThanToken) { return true; } - return token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType); + if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { + return true; + } + return token() === SyntaxKind.NewKeyword; } function skipParameterStart(): boolean { @@ -3691,7 +3715,7 @@ namespace ts { } function parseTypeWorker(noConditionalTypes?: boolean): TypeNode { - if (isStartOfFunctionType() || token() === SyntaxKind.NewKeyword) { + if (isStartOfFunctionTypeOrConstructorType()) { return parseFunctionOrConstructorType(); } const pos = getNodePos(); @@ -7440,11 +7464,9 @@ namespace ts { loop: while (true) { switch (tok) { case SyntaxKind.NewLineTrivia: - if (state >= JSDocState.SawAsterisk) { - state = JSDocState.BeginningOfLine; - // don't use pushComment here because we want to keep the margin unchanged - comments.push(scanner.getTokenText()); - } + state = JSDocState.BeginningOfLine; + // don't use pushComment here because we want to keep the margin unchanged + comments.push(scanner.getTokenText()); indent = 0; break; case SyntaxKind.AtToken: @@ -8678,7 +8700,7 @@ namespace ts { extractPragmas(pragmas, range, comment); } - context.pragmas = createMap() as PragmaMap; + context.pragmas = new Map() as PragmaMap; for (const pragma of pragmas) { if (context.pragmas.has(pragma.name)) { const currentValue = context.pragmas.get(pragma.name); @@ -8776,7 +8798,7 @@ namespace ts { }); } - const namedArgRegExCache = createMap(); + const namedArgRegExCache = new Map(); function getNamedArgRegEx(name: string): RegExp { if (namedArgRegExCache.has(name)) { return namedArgRegExCache.get(name)!; diff --git a/src/compiler/perfLogger.ts b/src/compiler/perfLogger.ts index 8ed8feac90c4c..f05e8a3bd1053 100644 --- a/src/compiler/perfLogger.ts +++ b/src/compiler/perfLogger.ts @@ -28,9 +28,11 @@ namespace ts { // See https://github.com/microsoft/typescript-etw for more information let etwModule; try { - // require() will throw an exception if the module is not installed + const etwModulePath = process.env.TS_ETW_MODULE_PATH ?? "./node_modules/@microsoft/typescript-etw"; + + // require() will throw an exception if the module is not found // It may also return undefined if not installed properly - etwModule = require("@microsoft/typescript-etw"); + etwModule = require(etwModulePath); } catch (e) { etwModule = undefined; diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 3da794c638b16..dcee41c2d2c70 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -8,9 +8,9 @@ namespace ts.performance { let enabled = false; let profilerStart = 0; - let counts: Map; - let marks: Map; - let measures: Map; + let counts: ESMap; + let marks: ESMap; + let measures: ESMap; export interface Timer { enter(): void; @@ -108,9 +108,9 @@ namespace ts.performance { /** Enables (and resets) performance measurements for the compiler. */ export function enable() { - counts = createMap(); - marks = createMap(); - measures = createMap(); + counts = new Map(); + marks = new Map(); + measures = new Map(); enabled = true; profilerStart = timestamp(); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8cee3aae854d7..132938d5fb8c7 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -71,7 +71,7 @@ namespace ts { /*@internal*/ // TODO(shkamat): update this after reworking ts build API export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { - const existingDirectories = createMap(); + const existingDirectories = new Map(); const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames); function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined { let text: string | undefined; @@ -126,7 +126,7 @@ namespace ts { } } - let outputFingerprints: Map; + let outputFingerprints: ESMap; function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) { if (!isWatchSet(options) || !system.createHash || !system.getModifiedTime) { system.writeFile(fileName, data, writeByteOrderMark); @@ -134,7 +134,7 @@ namespace ts { } if (!outputFingerprints) { - outputFingerprints = createMap(); + outputFingerprints = new Map(); } const hash = system.createHash(data); @@ -211,10 +211,10 @@ namespace ts { const originalDirectoryExists = host.directoryExists; const originalCreateDirectory = host.createDirectory; const originalWriteFile = host.writeFile; - const readFileCache = createMap(); - const fileExistsCache = createMap(); - const directoryExistsCache = createMap(); - const sourceFileCache = createMap(); + const readFileCache = new Map(); + const fileExistsCache = new Map(); + const directoryExistsCache = new Map(); + const sourceFileCache = new Map(); const readFileWithCache = (fileName: string): string | undefined => { const key = toPath(fileName); @@ -515,7 +515,7 @@ namespace ts { return []; } const resolutions: T[] = []; - const cache = createMap(); + const cache = new Map(); for (const name of names) { let result: T; if (cache.has(name)) { @@ -533,7 +533,7 @@ namespace ts { export const inferredTypesContainingFile = "__inferred type names__.ts"; interface DiagnosticCache { - perFile?: Map; + perFile?: ESMap; allDiagnostics?: readonly T[]; } @@ -702,19 +702,19 @@ namespace ts { let processingDefaultLibFiles: SourceFile[] | undefined; let processingOtherFiles: SourceFile[] | undefined; let files: SourceFile[]; - let symlinks: ReadonlyMap | undefined; + let symlinks: ReadonlyESMap | undefined; let commonSourceDirectory: string; let diagnosticsProducingTypeChecker: TypeChecker; let noDiagnosticsTypeChecker: TypeChecker; - let classifiableNames: UnderscoreEscapedMap; - const ambientModuleNameToUnmodifiedFileName = createMap(); + let classifiableNames: Set<__String>; + const ambientModuleNameToUnmodifiedFileName = new Map(); // Todo:: Use this to report why file was included in --extendedDiagnostics let refFileMap: MultiMap | undefined; const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache = {}; const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; - let resolvedTypeReferenceDirectives = createMap(); + let resolvedTypeReferenceDirectives = new Map(); let fileProcessingDiagnostics = createDiagnosticCollection(); // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules. @@ -729,10 +729,10 @@ namespace ts { // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. - const modulesWithElidedImports = createMap(); + const modulesWithElidedImports = new Map(); // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. - const sourceFilesFoundSearchingNodeModules = createMap(); + const sourceFilesFoundSearchingNodeModules = new Map(); performance.mark("beforeProgram"); @@ -748,7 +748,7 @@ namespace ts { const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Map storing if there is emit blocking diagnostics for given input - const hasEmitBlockingDiagnostics = createMap(); + const hasEmitBlockingDiagnostics = new Map(); let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | null | undefined; let moduleResolutionCache: ModuleResolutionCache | undefined; @@ -783,9 +783,9 @@ namespace ts { // Map from a stringified PackageId to the source file with that id. // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. - const packageIdToSourceFile = createMap(); + const packageIdToSourceFile = new Map(); // Maps from a SourceFile's `.path` to the name of the package it was imported with. - let sourceFileToPackageName = createMap(); + let sourceFileToPackageName = new Map(); // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it. let redirectTargetsMap = createMultiMap(); @@ -795,17 +795,19 @@ namespace ts { * - false if sourceFile missing for source of project reference redirect * - undefined otherwise */ - const filesByName = createMap(); + const filesByName = new Map(); let missingFilePaths: readonly Path[] | undefined; // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing - const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap() : undefined; + const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? new Map() : undefined; // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files let resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined; - let projectReferenceRedirects: Map | undefined; - let mapFromFileToProjectReferenceRedirects: Map | undefined; - let mapFromToProjectReferenceRedirectSource: Map | undefined; + let projectReferenceRedirects: ESMap | undefined; + let mapFromFileToProjectReferenceRedirects: ESMap | undefined; + let mapFromToProjectReferenceRedirectSource: ESMap | undefined; + + let skippedTrippleSlashReferences: Set | undefined; const useSourceOfProjectReferenceRedirect = !!host.useSourceOfProjectReferenceRedirect?.() && !options.disableSourceOfProjectReferenceRedirect; @@ -928,6 +930,7 @@ namespace ts { getSourceFiles: () => files, getMissingFilePaths: () => missingFilePaths!, // TODO: GH#18217 getRefFileMap: () => refFileMap, + getSkippedTrippleSlashReferences: () => skippedTrippleSlashReferences, getFilesByNameMap: () => filesByName, getCompilerOptions: () => options, getSyntacticDiagnostics, @@ -1051,10 +1054,10 @@ namespace ts { if (!classifiableNames) { // Initialize a checker so that all our files are bound. getTypeChecker(); - classifiableNames = createUnderscoreEscapedMap(); + classifiableNames = new Set(); for (const sourceFile of files) { - copyEntries(sourceFile.classifiableNames!, classifiableNames); + sourceFile.classifiableNames?.forEach(value => classifiableNames.add(value)); } } @@ -1236,8 +1239,6 @@ namespace ts { return oldProgram.structureIsReused = StructureIsReused.Not; } - Debug.assert(!(oldProgram.structureIsReused! & (StructureIsReused.Completely | StructureIsReused.SafeModules))); - // there is an old program, check if we can reuse its structure const oldRootNames = oldProgram.getRootFileNames(); if (!arrayIsEqualTo(oldRootNames, rootNames)) { @@ -1270,7 +1271,8 @@ namespace ts { const oldSourceFiles = oldProgram.getSourceFiles(); const enum SeenPackageName { Exists, Modified } - const seenPackageNames = createMap(); + const seenPackageNames = new Map(); + const oldSkippedTrippleSlashReferences = oldProgram.getSkippedTrippleSlashReferences(); for (const oldSourceFile of oldSourceFiles) { let newSourceFile = host.getSourceFileByPath @@ -1343,6 +1345,11 @@ namespace ts { oldProgram.structureIsReused = StructureIsReused.SafeModules; } + if (oldSkippedTrippleSlashReferences?.has(oldSourceFile.path) && includeTripleslashReferencesFrom(newSourceFile)) { + // tripleslash reference resolution is now allowed + oldProgram.structureIsReused = StructureIsReused.SafeModules; + } + // check imports and module augmentations collectExternalModuleReferences(newSourceFile); if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) { @@ -1430,6 +1437,7 @@ namespace ts { missingFilePaths = oldProgram.getMissingFilePaths(); refFileMap = oldProgram.getRefFileMap(); + skippedTrippleSlashReferences = oldSkippedTrippleSlashReferences; // update fileName -> file mapping Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length); @@ -2178,7 +2186,7 @@ namespace ts { const r = /import|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null const node = getNodeAtPosition(file, r.lastIndex); - if (isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { + if (isJavaScriptFile && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { imports = append(imports, node.arguments[0]); } // we have to check the argument list has length of 1. We will still have to process these even though we have parsing error. @@ -2571,7 +2579,7 @@ namespace ts { function getSourceOfProjectReferenceRedirect(file: string) { if (!isDeclarationFileName(file)) return undefined; if (mapFromToProjectReferenceRedirectSource === undefined) { - mapFromToProjectReferenceRedirectSource = createMap(); + mapFromToProjectReferenceRedirectSource = new Map(); forEachResolvedProjectReference(resolvedRef => { if (resolvedRef) { const out = outFile(resolvedRef.commandLine.options); @@ -2649,9 +2657,17 @@ namespace ts { return projectReferenceRedirects.get(projectReferencePath) || undefined; } + function includeTripleslashReferencesFrom(file: SourceFile) { + return !host.includeTripleslashReferencesFrom || host.includeTripleslashReferencesFrom(file.originalFileName); + } + function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) { + if (!includeTripleslashReferencesFrom(file)) { + (skippedTrippleSlashReferences ||= new Set()).add(file.path); + return; + } forEach(file.referencedFiles, (ref, index) => { - const referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName); + const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName); processSourceFile( referencedFileName, isDefaultLib, @@ -3452,7 +3468,7 @@ namespace ts { return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; } - function getProbableSymlinks(): ReadonlyMap { + function getProbableSymlinks(): ReadonlyESMap { if (host.getSymlinks) { return host.getSymlinks(); } @@ -3479,8 +3495,8 @@ namespace ts { function updateHostForUseSourceOfProjectReferenceRedirect(host: HostForUseSourceOfProjectReferenceRedirect) { let setOfDeclarationDirectories: Set | undefined; - let symlinkedDirectories: Map | undefined; - let symlinkedFiles: Map | undefined; + let symlinkedDirectories: ESMap | undefined; + let symlinkedFiles: ESMap | undefined; const originalFileExists = host.compilerHost.fileExists; const originalDirectoryExists = host.compilerHost.directoryExists; diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index dc79fe0fabff9..56ea6a03e8047 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -11,9 +11,10 @@ namespace ts { invalidateResolutionsOfFailedLookupLocations(): boolean; invalidateResolutionOfFile(filePath: Path): void; + removeRelativeNoResolveResolutionsOfFile(filePath: Path): boolean; removeResolutionsOfFile(filePath: Path): void; removeResolutionsFromProjectReferenceRedirects(filePath: Path): void; - setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map): void; + setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: ESMap): void; createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; hasChangedAutomaticTypeDirectiveNames(): boolean; @@ -141,10 +142,24 @@ namespace ts { type GetResolutionWithResolvedFileName = (resolution: T) => R | undefined; - export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache { + export enum ResolutionKind { + All, + RelativeReferencesInOpenFileOnly + } + + const noResolveResolvedModule: ResolvedModuleWithFailedLookupLocations = { + resolvedModule: undefined, + failedLookupLocations: [] + }; + const noResolveResolvedTypeReferenceDirective: ResolvedTypeReferenceDirectiveWithFailedLookupLocations = { + resolvedTypeReferenceDirective: undefined, + failedLookupLocations: [] + }; + + export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, resolutionKind: ResolutionKind, logChangesWhenResolvingModule: boolean): ResolutionCache { let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; let filesWithInvalidatedResolutions: Set | undefined; - let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap | undefined; + let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyESMap | undefined; const nonRelativeExternalModuleResolutions = createMultiMap(); const resolutionsWithFailedLookups: ResolutionWithFailedLookupLocations[] = []; @@ -161,8 +176,8 @@ namespace ts { // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file. // The key in the map is source file's path. // The values are Map of resolutions with key being name lookedup. - const resolvedModuleNames = new Map>(); - const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); + const resolvedModuleNames = new Map>(); + const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); const nonRelativeModuleNameCache: CacheWithRedirects = createCacheWithRedirects(); const moduleResolutionCache = createModuleResolutionCacheWithMaps( perDirectoryResolvedModuleNames, @@ -171,8 +186,8 @@ namespace ts { resolutionHost.getCanonicalFileName ); - const resolvedTypeReferenceDirectives = new Map>(); - const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); + const resolvedTypeReferenceDirectives = new Map>(); + const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); /** * These are the extensions that failed lookup files will have by default, @@ -181,15 +196,15 @@ namespace ts { * Note that .d.ts file also has .d.ts extension hence will be part of default extensions */ const failedLookupDefaultExtensions = [Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx, Extension.Json]; - const customFailedLookupPaths = createMap(); + const customFailedLookupPaths = new Map(); - const directoryWatchesOfFailedLookups = createMap(); + const directoryWatchesOfFailedLookups = new Map(); const rootDir = rootDirForResolution && removeTrailingDirectorySeparator(getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory())); const rootPath = (rootDir && resolutionHost.toPath(rootDir)) as Path; // TODO: GH#18217 const rootSplitLength = rootPath !== undefined ? rootPath.split(directorySeparator).length : 0; // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames - const typeRootsWatches = createMap(); + const typeRootsWatches = new Map(); return { startRecordingFilesWithChangedResolutions, @@ -206,6 +221,7 @@ namespace ts { hasChangedAutomaticTypeDirectiveNames: () => hasChangedAutomaticTypeDirectiveNames, invalidateResolutionOfFile, invalidateResolutionsOfFailedLookupLocations, + removeRelativeNoResolveResolutionsOfFile, setFilesWithInvalidatedNonRelativeUnresolvedImports, createHasInvalidatedResolution, updateTypeRootsWatch, @@ -334,27 +350,28 @@ namespace ts { names: readonly string[]; containingFile: string; redirectedReference: ResolvedProjectReference | undefined; - cache: Map>; - perDirectoryCacheWithRedirects: CacheWithRedirects>; + cache: ESMap>; + perDirectoryCacheWithRedirects: CacheWithRedirects>; loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T; getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName; shouldRetryResolution: (t: T) => boolean; reusedNames?: readonly string[]; logChanges?: boolean; + noResolveResolution: T; } function resolveNamesWithLocalCache({ names, containingFile, redirectedReference, cache, perDirectoryCacheWithRedirects, - loader, getResolutionWithResolvedFileName, + loader, getResolutionWithResolvedFileName, noResolveResolution, shouldRetryResolution, reusedNames, logChanges }: ResolveNamesWithLocalCacheInput): (R | undefined)[] { const path = resolutionHost.toPath(containingFile); - const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!; + const resolutionsInFile = cache.get(path) || cache.set(path, new Map()).get(path)!; const dirPath = getDirectoryPath(path); const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); let perDirectoryResolution = perDirectoryCache.get(dirPath); if (!perDirectoryResolution) { - perDirectoryResolution = createMap(); + perDirectoryResolution = new Map(); perDirectoryCache.set(dirPath, perDirectoryResolution); } const resolvedModules: (R | undefined)[] = []; @@ -368,7 +385,7 @@ namespace ts { !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path : !!redirectedReference; - const seenNamesInFile = createMap(); + const seenNamesInFile = new Map(); for (const name of names) { let resolution = resolutionsInFile.get(name); // Resolution is valid if it is present and not invalidated @@ -382,7 +399,10 @@ namespace ts { resolution = resolutionInDirectory; } else { - resolution = loader(name, containingFile, compilerOptions, resolutionHost.getCompilerHost?.() || resolutionHost, redirectedReference); + resolution = resolutionKind === ResolutionKind.All || + (isExternalModuleNameRelative(name) && resolutionHost.fileIsOpen(path)) ? + loader(name, containingFile, compilerOptions, resolutionHost.getCompilerHost?.() || resolutionHost, redirectedReference) : + noResolveResolution; perDirectoryResolution.set(name, resolution); } resolutionsInFile.set(name, resolution); @@ -441,6 +461,7 @@ namespace ts { loader: resolveTypeReferenceDirective, getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective, shouldRetryResolution: resolution => resolution.resolvedTypeReferenceDirective === undefined, + noResolveResolution: noResolveResolvedTypeReferenceDirective, }); } @@ -455,7 +476,8 @@ namespace ts { getResolutionWithResolvedFileName: getResolvedModule, shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension), reusedNames, - logChanges: logChangesWhenResolvingModule + logChanges: logChangesWhenResolvingModule, + noResolveResolution: noResolveResolvedModule, }); } @@ -684,7 +706,7 @@ namespace ts { } function removeResolutionsOfFileFromCache( - cache: Map>, + cache: ESMap>, filePath: Path, getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName, ) { @@ -724,7 +746,7 @@ namespace ts { for (const containingFilePath of Debug.assertDefined(resolution.files)) { (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = new Set())).add(containingFilePath); // When its a file with inferred types resolution, invalidate type reference directive resolution - hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames || containingFilePath.endsWith(inferredTypesContainingFile); + hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames || endsWith(containingFilePath, inferredTypesContainingFile); } } return invalidated; @@ -741,7 +763,32 @@ namespace ts { } } - function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyMap) { + function removeRelativeNoResolveResolutionsOfFileFromCache( + cache: ESMap>, + filePath: Path, + noResolveResolution: T, + ) { + Debug.assert(resolutionKind === ResolutionKind.RelativeReferencesInOpenFileOnly); + // Deleted file, stop watching failed lookups for all the resolutions in the file + const resolutions = cache.get(filePath); + if (!resolutions) return false; + let invalidated = false; + resolutions.forEach((resolution, name) => { + if (resolution === noResolveResolution && isExternalModuleNameRelative(name)) { + resolutions.delete(name); + invalidated = true; + } + }); + return invalidated; + } + + function removeRelativeNoResolveResolutionsOfFile(filePath: Path) { + let invalidated = removeRelativeNoResolveResolutionsOfFileFromCache(resolvedModuleNames, filePath, noResolveResolvedModule); + invalidated = removeRelativeNoResolveResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, noResolveResolvedTypeReferenceDirective) || invalidated; + return invalidated; + } + + function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyESMap) { Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined); filesWithInvalidatedNonRelativeUnresolvedImports = filesMap; } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index ab2a37032ced2..77ec82ffef760 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -34,6 +34,7 @@ namespace ts { getTokenFlags(): TokenFlags; reScanGreaterToken(): SyntaxKind; reScanSlashToken(): SyntaxKind; + reScanAsteriskEqualsToken(): SyntaxKind; reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind; reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind; scanJsxIdentifier(): SyntaxKind; @@ -153,9 +154,9 @@ namespace ts { of: SyntaxKind.OfKeyword, }; - const textToKeyword = createMapFromTemplate(textToKeywordObj); + const textToKeyword = new Map(getEntries(textToKeywordObj)); - const textToToken = createMapFromTemplate({ + const textToToken = new Map(getEntries({ ...textToKeywordObj, "{": SyntaxKind.OpenBraceToken, "}": SyntaxKind.CloseBraceToken, @@ -217,7 +218,7 @@ namespace ts { "??=": SyntaxKind.QuestionQuestionEqualsToken, "@": SyntaxKind.AtToken, "`": SyntaxKind.BacktickToken - }); + })); /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers @@ -330,7 +331,7 @@ namespace ts { lookupInUnicodeMap(code, unicodeES3IdentifierPart); } - function makeReverseMap(source: Map): string[] { + function makeReverseMap(source: ESMap): string[] { const result: string[] = []; source.forEach((value, name) => { result[value] = name; @@ -954,6 +955,7 @@ namespace ts { getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags, getTokenFlags: () => tokenFlags, reScanGreaterToken, + reScanAsteriskEqualsToken, reScanSlashToken, reScanTemplateToken, reScanTemplateHeadOrNoSubstitutionTemplate, @@ -2086,6 +2088,12 @@ namespace ts { return token; } + function reScanAsteriskEqualsToken(): SyntaxKind { + Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); + pos = tokenPos + 1; + return token = SyntaxKind.EqualsToken; + } + function reScanSlashToken(): SyntaxKind { if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) { let p = tokenPos + 1; @@ -2352,8 +2360,12 @@ namespace ts { return token = SyntaxKind.WhitespaceTrivia; case CharacterCodes.at: return token = SyntaxKind.AtToken; - case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: + if (text.charCodeAt(pos) === CharacterCodes.lineFeed) { + pos++; + } + // falls through + case CharacterCodes.lineFeed: tokenFlags |= TokenFlags.PrecedingLineBreak; return token = SyntaxKind.NewLineTrivia; case CharacterCodes.asterisk: diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 3e70d335566bb..0db89a5830fd2 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -12,11 +12,11 @@ namespace ts { // Current source map file and its index in the sources list const rawSources: string[] = []; const sources: string[] = []; - const sourceToSourceIndexMap = createMap(); + const sourceToSourceIndexMap = new Map(); let sourcesContent: (string | null)[] | undefined; const names: string[] = []; - let nameToNameIndexMap: Map | undefined; + let nameToNameIndexMap: ESMap | undefined; let mappings = ""; // Last recorded and encoded mappings @@ -84,7 +84,7 @@ namespace ts { function addName(name: string) { enter(); - if (!nameToNameIndexMap) nameToNameIndexMap = createMap(); + if (!nameToNameIndexMap) nameToNameIndexMap = new Map(); let nameIndex = nameToNameIndexMap.get(name); if (nameIndex === undefined) { nameIndex = names.length; diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index fcbaddb966ed2..1662a7ef31096 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -538,7 +538,7 @@ namespace ts { }; } - type InvokeMap = Map; + type InvokeMap = ESMap; function invokeCallbacks(dirPath: Path, fileName: string): void; function invokeCallbacks(dirPath: Path, invokeMap: InvokeMap, fileNames: string[] | undefined): void; function invokeCallbacks(dirPath: Path, fileNameOrInvokeMap: string | InvokeMap, fileNames?: string[]) { diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 774ded70dfef4..01e3d7c7896a8 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -890,7 +890,7 @@ namespace ts { } function getPrivateIdentifierEnvironment() { - return currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = createUnderscoreEscapedMap()); + return currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = new Map()); } function getPendingExpressions() { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 8d05347bc6f31..477ccef943790 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -60,7 +60,7 @@ namespace ts { let enclosingDeclaration: Node; let necessaryTypeReferences: Set | undefined; let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; - let lateStatementReplacementMap: Map>; + let lateStatementReplacementMap: ESMap>; let suppressNewDiagnosticContexts: boolean; let exportedModulesFromDeclarationEmit: Symbol[] | undefined; @@ -81,8 +81,8 @@ namespace ts { let errorNameNode: DeclarationName | undefined; let currentSourceFile: SourceFile; - let refs: Map; - let libs: Map; + let refs: ESMap; + let libs: ESMap; let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass const resolver = context.getEmitResolver(); const options = context.getCompilerOptions(); @@ -107,7 +107,7 @@ namespace ts { } // Otherwise we should emit a path-based reference const container = getSourceFileOfNode(node); - refs.set("" + getOriginalNodeId(container), container); + refs.set(getOriginalNodeId(container), container); } function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) { @@ -231,8 +231,8 @@ namespace ts { if (node.kind === SyntaxKind.Bundle) { isBundledEmit = true; - refs = createMap(); - libs = createMap(); + refs = new Map(); + libs = new Map(); let hasNoDefaultLib = false; const bundle = factory.createBundle(map(node.sourceFiles, sourceFile => { @@ -242,7 +242,7 @@ namespace ts { enclosingDeclaration = sourceFile; lateMarkedStatements = undefined; suppressNewDiagnosticContexts = false; - lateStatementReplacementMap = createMap(); + lateStatementReplacementMap = new Map(); getSymbolAccessibilityDiagnostic = throwDiagnostic; needsScopeFixMarker = false; resultHasScopeMarker = false; @@ -296,10 +296,10 @@ namespace ts { resultHasExternalModuleIndicator = false; suppressNewDiagnosticContexts = false; lateMarkedStatements = undefined; - lateStatementReplacementMap = createMap(); + lateStatementReplacementMap = new Map(); necessaryTypeReferences = undefined; - refs = collectReferences(currentSourceFile, createMap()); - libs = collectLibs(currentSourceFile, createMap()); + refs = collectReferences(currentSourceFile, new Map()); + libs = collectLibs(currentSourceFile, new Map()); const references: FileReference[] = []; const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); const referenceVisitor = mapReferencesIntoArray(references, outputFilePath); @@ -402,18 +402,18 @@ namespace ts { } } - function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: Map) { + function collectReferences(sourceFile: SourceFile | UnparsedSource, ret: ESMap) { if (noResolve || (!isUnparsedSource(sourceFile) && isSourceFileJS(sourceFile))) return ret; forEach(sourceFile.referencedFiles, f => { const elem = host.getSourceFileFromReference(sourceFile, f); if (elem) { - ret.set("" + getOriginalNodeId(elem), elem); + ret.set(getOriginalNodeId(elem), elem); } }); return ret; } - function collectLibs(sourceFile: SourceFile | UnparsedSource, ret: Map) { + function collectLibs(sourceFile: SourceFile | UnparsedSource, ret: ESMap) { forEach(sourceFile.libReferenceDirectives, ref => { const lib = host.getLibFileFromReference(ref); if (lib) { @@ -772,7 +772,7 @@ namespace ts { needsDeclare = i.parent && isSourceFile(i.parent) && !(isExternalModule(i.parent) && isBundledEmit); const result = transformTopLevelDeclaration(i); needsDeclare = priorNeedsDeclare; - lateStatementReplacementMap.set("" + getOriginalNodeId(i), result); + lateStatementReplacementMap.set(getOriginalNodeId(i), result); } // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list @@ -781,7 +781,7 @@ namespace ts { function visitLateVisibilityMarkedStatements(statement: Statement) { if (isLateVisibilityPaintedStatement(statement)) { - const key = "" + getOriginalNodeId(statement); + const key = getOriginalNodeId(statement); if (lateStatementReplacementMap.has(key)) { const result = lateStatementReplacementMap.get(key); lateStatementReplacementMap.delete(key); @@ -1103,7 +1103,7 @@ namespace ts { const result = transformTopLevelDeclaration(input); // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass - lateStatementReplacementMap.set("" + getOriginalNodeId(input), result); + lateStatementReplacementMap.set(getOriginalNodeId(input), result); return input; } @@ -1305,7 +1305,7 @@ namespace ts { needsDeclare = false; visitNode(inner, visitDeclarationStatements); // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done) - const id = "" + getOriginalNodeId(inner!); // TODO: GH#18217 + const id = getOriginalNodeId(inner!); // TODO: GH#18217 const body = lateStatementReplacementMap.get(id); lateStatementReplacementMap.delete(id); return cleanup(factory.updateModuleDeclaration( diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index 1294739ef961b..ebb453ee83d9a 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -447,11 +447,12 @@ namespace ts { function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; // Heritage clause is written by user so it can always be named - if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) { + if (isClassDeclaration(node.parent.parent)) { // Class or Interface implemented/extended is inaccessible diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ? Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : - Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1; + node.parent.parent.name ? Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1 : + Diagnostics.extends_clause_of_exported_class_has_or_is_using_private_name_0; } else { // interface is inaccessible diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index f9d94f3ee5976..02ff2c261e536 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -72,15 +72,15 @@ namespace ts { * set of labels that occurred inside the converted loop * used to determine if labeled jump can be emitted as is or it should be dispatched to calling code */ - labels?: Map; + labels?: ESMap; /* * collection of labeled jumps that transfer control outside the converted loop. * maps store association 'label -> labelMarker' where * - label - value of label as it appear in code * - label marker - return value that should be interpreted by calling code as 'jump to { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; + } + + declare const a: Desc<[string, number, boolean], object>; + const b = a.bind("", 1); // Desc<[boolean], object> + + // Repro from #39607 + + declare function getUser(id: string, options?: { x?: string }): string; + + declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; + + function callApi(method: (...args: [...T, object]) => U) { + return (...args: [...T]) => method(...args, {}); + } + + callApi(getUser); + callApi(getOrgUser); \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.js b/tests/baselines/reference/variadicTuples1.js index c1d364682952b..b75ffcb37009d 100644 --- a/tests/baselines/reference/variadicTuples1.js +++ b/tests/baselines/reference/variadicTuples1.js @@ -332,6 +332,48 @@ call('hello', 32, (a, b) => 42); // Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure call(...sa, (...x) => 42); + +// No inference to ending optional elements (except with identical structure) + +declare function f20(args: [...T, number?]): T; + +function f21(args: [...U, number?]) { + let v1 = f20(args); // U + let v2 = f20(["foo", "bar"]); // [] + let v3 = f20(["foo", 42]); // [] +} + +declare function f22(args: [...T, number]): T; +declare function f22(args: [...T]): T; + +function f23(args: [...U, number]) { + let v1 = f22(args); // U + let v2 = f22(["foo", "bar"]); // [string, string] + let v3 = f22(["foo", 42]); // [string] +} + +// Repro from #39327 + +interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} + +declare const a: Desc<[string, number, boolean], object>; +const b = a.bind("", 1); // Desc<[boolean], object> + +// Repro from #39607 + +declare function getUser(id: string, options?: { x?: string }): string; + +declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; + +function callApi(method: (...args: [...T, object]) => U) { + return (...args: [...T]) => method(...args, {}); +} + +callApi(getUser); +callApi(getOrgUser); //// [variadicTuples1.js] @@ -528,6 +570,28 @@ call.apply(void 0, __spreadArrays(sa, [function () { } return 42; }])); +function f21(args) { + var v1 = f20(args); // U + var v2 = f20(["foo", "bar"]); // [] + var v3 = f20(["foo", 42]); // [] +} +function f23(args) { + var v1 = f22(args); // U + var v2 = f22(["foo", "bar"]); // [string, string] + var v3 = f22(["foo", 42]); // [string] +} +var b = a.bind("", 1); // Desc<[boolean], object> +function callApi(method) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return method.apply(void 0, __spreadArrays(args, [{}])); + }; +} +callApi(getUser); +callApi(getOrgUser); //// [variadicTuples1.d.ts] @@ -669,3 +733,22 @@ declare const c22: (...b: string[]) => number; declare function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]): R; declare function fn10(a: string, b: number, c: boolean): string[]; declare function call(...args: [...T, (...args: T) => R]): [T, R]; +declare function f20(args: [...T, number?]): T; +declare function f21(args: [...U, number?]): void; +declare function f22(args: [...T, number]): T; +declare function f22(args: [...T]): T; +declare function f23(args: [...U, number]): void; +interface Desc { + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} +declare const a: Desc<[string, number, boolean], object>; +declare const b: Desc<[boolean], object>; +declare function getUser(id: string, options?: { + x?: string; +}): string; +declare function getOrgUser(id: string, orgId: number, options?: { + y?: number; + z?: boolean; +}): void; +declare function callApi(method: (...args: [...T, object]) => U): (...args_0: T) => U; diff --git a/tests/baselines/reference/variadicTuples1.symbols b/tests/baselines/reference/variadicTuples1.symbols index fe83d5f0bd7cc..c8dce6f67e6a7 100644 --- a/tests/baselines/reference/variadicTuples1.symbols +++ b/tests/baselines/reference/variadicTuples1.symbols @@ -1141,3 +1141,146 @@ call(...sa, (...x) => 42); >sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) >x : Symbol(x, Decl(variadicTuples1.ts, 332, 13)) +// No inference to ending optional elements (except with identical structure) + +declare function f20(args: [...T, number?]): T; +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 332, 26)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 336, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 21)) + +function f21(args: [...U, number?]) { +>f21 : Symbol(f21, Decl(variadicTuples1.ts, 336, 73)) +>U : Symbol(U, Decl(variadicTuples1.ts, 338, 13)) +>args : Symbol(args, Decl(variadicTuples1.ts, 338, 33)) +>U : Symbol(U, Decl(variadicTuples1.ts, 338, 13)) + + let v1 = f20(args); // U +>v1 : Symbol(v1, Decl(variadicTuples1.ts, 339, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 332, 26)) +>args : Symbol(args, Decl(variadicTuples1.ts, 338, 33)) + + let v2 = f20(["foo", "bar"]); // [] +>v2 : Symbol(v2, Decl(variadicTuples1.ts, 340, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 332, 26)) + + let v3 = f20(["foo", 42]); // [] +>v3 : Symbol(v3, Decl(variadicTuples1.ts, 341, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 332, 26)) +} + +declare function f22(args: [...T, number]): T; +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) +>T : Symbol(T, Decl(variadicTuples1.ts, 344, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 344, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 344, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 344, 21)) + +declare function f22(args: [...T]): T; +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 345, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 21)) + +function f23(args: [...U, number]) { +>f23 : Symbol(f23, Decl(variadicTuples1.ts, 345, 64)) +>U : Symbol(U, Decl(variadicTuples1.ts, 347, 13)) +>args : Symbol(args, Decl(variadicTuples1.ts, 347, 33)) +>U : Symbol(U, Decl(variadicTuples1.ts, 347, 13)) + + let v1 = f22(args); // U +>v1 : Symbol(v1, Decl(variadicTuples1.ts, 348, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) +>args : Symbol(args, Decl(variadicTuples1.ts, 347, 33)) + + let v2 = f22(["foo", "bar"]); // [string, string] +>v2 : Symbol(v2, Decl(variadicTuples1.ts, 349, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) + + let v3 = f22(["foo", 42]); // [string] +>v3 : Symbol(v3, Decl(variadicTuples1.ts, 350, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 342, 1), Decl(variadicTuples1.ts, 344, 72)) +} + +// Repro from #39327 + +interface Desc { +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35)) + + readonly f: (...args: A) => T; +>f : Symbol(Desc.f, Decl(variadicTuples1.ts, 355, 40)) +>args : Symbol(args, Decl(variadicTuples1.ts, 356, 17)) +>A : Symbol(A, Decl(variadicTuples1.ts, 355, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 355, 35)) + + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +>this : Symbol(this, Decl(variadicTuples1.ts, 357, 54)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +>args : Symbol(args, Decl(variadicTuples1.ts, 357, 82)) +>T : Symbol(T, Decl(variadicTuples1.ts, 357, 9)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) +>U : Symbol(U, Decl(variadicTuples1.ts, 357, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 357, 50)) +} + +declare const a: Desc<[string, number, boolean], object>; +>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 351, 1)) + +const b = a.bind("", 1); // Desc<[boolean], object> +>b : Symbol(b, Decl(variadicTuples1.ts, 361, 5)) +>a.bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) +>a : Symbol(a, Decl(variadicTuples1.ts, 360, 13)) +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 356, 34)) + +// Repro from #39607 + +declare function getUser(id: string, options?: { x?: string }): string; +>getUser : Symbol(getUser, Decl(variadicTuples1.ts, 361, 24)) +>id : Symbol(id, Decl(variadicTuples1.ts, 365, 25)) +>options : Symbol(options, Decl(variadicTuples1.ts, 365, 36)) +>x : Symbol(x, Decl(variadicTuples1.ts, 365, 48)) + +declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; +>getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 365, 71)) +>id : Symbol(id, Decl(variadicTuples1.ts, 367, 28)) +>orgId : Symbol(orgId, Decl(variadicTuples1.ts, 367, 39)) +>options : Symbol(options, Decl(variadicTuples1.ts, 367, 54)) +>y : Symbol(y, Decl(variadicTuples1.ts, 367, 66)) +>z : Symbol(z, Decl(variadicTuples1.ts, 367, 78)) + +function callApi(method: (...args: [...T, object]) => U) { +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 367, 100)) +>T : Symbol(T, Decl(variadicTuples1.ts, 369, 17)) +>U : Symbol(U, Decl(variadicTuples1.ts, 369, 42)) +>method : Symbol(method, Decl(variadicTuples1.ts, 369, 53)) +>args : Symbol(args, Decl(variadicTuples1.ts, 369, 62)) +>T : Symbol(T, Decl(variadicTuples1.ts, 369, 17)) +>U : Symbol(U, Decl(variadicTuples1.ts, 369, 42)) + + return (...args: [...T]) => method(...args, {}); +>args : Symbol(args, Decl(variadicTuples1.ts, 370, 12)) +>T : Symbol(T, Decl(variadicTuples1.ts, 369, 17)) +>method : Symbol(method, Decl(variadicTuples1.ts, 369, 53)) +>args : Symbol(args, Decl(variadicTuples1.ts, 370, 12)) +} + +callApi(getUser); +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 367, 100)) +>getUser : Symbol(getUser, Decl(variadicTuples1.ts, 361, 24)) + +callApi(getOrgUser); +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 367, 100)) +>getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 365, 71)) + diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types index 9c78c1f88ac89..dce37b089e51c 100644 --- a/tests/baselines/reference/variadicTuples1.types +++ b/tests/baselines/reference/variadicTuples1.types @@ -1186,3 +1186,137 @@ call(...sa, (...x) => 42); >x : any[] >42 : 42 +// No inference to ending optional elements (except with identical structure) + +declare function f20(args: [...T, number?]): T; +>f20 : (args: [...T, number?]) => T +>args : [...T, (number | undefined)?] + +function f21(args: [...U, number?]) { +>f21 : (args: [...U, number?]) => void +>args : [...U, (number | undefined)?] + + let v1 = f20(args); // U +>v1 : U +>f20(args) : U +>f20 : (args: [...T, (number | undefined)?]) => T +>args : [...U, (number | undefined)?] + + let v2 = f20(["foo", "bar"]); // [] +>v2 : [] +>f20(["foo", "bar"]) : [] +>f20 : (args: [...T, (number | undefined)?]) => T +>["foo", "bar"] : [string, string] +>"foo" : "foo" +>"bar" : "bar" + + let v3 = f20(["foo", 42]); // [] +>v3 : [] +>f20(["foo", 42]) : [] +>f20 : (args: [...T, (number | undefined)?]) => T +>["foo", 42] : [string, number] +>"foo" : "foo" +>42 : 42 +} + +declare function f22(args: [...T, number]): T; +>f22 : { (args: [...T, number]): T; (args: [...T]): T; } +>args : [...T, number] + +declare function f22(args: [...T]): T; +>f22 : { (args: [...T, number]): T; (args: [...T]): T; } +>args : [...T] + +function f23(args: [...U, number]) { +>f23 : (args: [...U, number]) => void +>args : [...U, number] + + let v1 = f22(args); // U +>v1 : U +>f22(args) : U +>f22 : { (args: [...T, number]): T; (args: [...T]): T; } +>args : [...U, number] + + let v2 = f22(["foo", "bar"]); // [string, string] +>v2 : [string, string] +>f22(["foo", "bar"]) : [string, string] +>f22 : { (args: [...T, number]): T; (args: [...T]): T; } +>["foo", "bar"] : [string, string] +>"foo" : "foo" +>"bar" : "bar" + + let v3 = f22(["foo", 42]); // [string] +>v3 : [string] +>f22(["foo", 42]) : [string] +>f22 : { (args: [...T, number]): T; (args: [...T]): T; } +>["foo", 42] : [string, number] +>"foo" : "foo" +>42 : 42 +} + +// Repro from #39327 + +interface Desc { + readonly f: (...args: A) => T; +>f : (...args: A) => T +>args : A + + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +>bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>this : Desc<[...T, ...U], R> +>args : T +} + +declare const a: Desc<[string, number, boolean], object>; +>a : Desc<[string, number, boolean], object> + +const b = a.bind("", 1); // Desc<[boolean], object> +>b : Desc<[boolean], object> +>a.bind("", 1) : Desc<[boolean], object> +>a.bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>a : Desc<[string, number, boolean], object> +>bind : (this: Desc<[...T, ...U], R>, ...args: T) => Desc<[...U], R> +>"" : "" +>1 : 1 + +// Repro from #39607 + +declare function getUser(id: string, options?: { x?: string }): string; +>getUser : (id: string, options?: { x?: string | undefined; } | undefined) => string +>id : string +>options : { x?: string | undefined; } | undefined +>x : string | undefined + +declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; +>getOrgUser : (id: string, orgId: number, options?: { y?: number | undefined; z?: boolean | undefined; } | undefined) => void +>id : string +>orgId : number +>options : { y?: number | undefined; z?: boolean | undefined; } | undefined +>y : number | undefined +>z : boolean | undefined + +function callApi(method: (...args: [...T, object]) => U) { +>callApi : (method: (...args_0: T, args_1: object) => U) => (...args_0: T) => U +>method : (...args_0: T, args_1: object) => U +>args : [...T, object] + + return (...args: [...T]) => method(...args, {}); +>(...args: [...T]) => method(...args, {}) : (...args_0: T) => U +>args : [...T] +>method(...args, {}) : U +>method : (...args_0: T, args_1: object) => U +>...args : T[number] +>args : [...T] +>{} : {} +} + +callApi(getUser); +>callApi(getUser) : (id: string) => string +>callApi : (method: (...args_0: T, args_1: object) => U) => (...args_0: T) => U +>getUser : (id: string, options?: { x?: string | undefined; } | undefined) => string + +callApi(getOrgUser); +>callApi(getOrgUser) : (id: string, orgId: number) => void +>callApi : (method: (...args_0: T, args_1: object) => U) => (...args_0: T) => U +>getOrgUser : (id: string, orgId: number, options?: { y?: number | undefined; z?: boolean | undefined; } | undefined) => void + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js index 91fdb7d3e1aed..74abf4a86a958 100644 --- a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js @@ -72,7 +72,7 @@ var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js index 0b39a6176efde..3dad3331424ef 100644 --- a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js @@ -72,7 +72,7 @@ var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { diff --git a/tests/cases/compiler/circularBaseTypes.ts b/tests/cases/compiler/circularBaseTypes.ts new file mode 100644 index 0000000000000..d858b2ebfc00d --- /dev/null +++ b/tests/cases/compiler/circularBaseTypes.ts @@ -0,0 +1,12 @@ +// @strict: true +// @declaration: true + +// Repro from #38098 + +type M = { value: T }; +interface M2 extends M {}; // Error +type M3 = M2[keyof M2]; // Error + +function f(m: M3) { + return m.value; +} diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index 646c85f069f89..786b61aea211b 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -178,4 +178,12 @@ function f18() { x.unshift("hello"); x[2] = true; return x; // (string | number | boolean)[] -} \ No newline at end of file +} + +// Repro from #39470 + +declare function foo(arg: { val: number }[]): void; + +let arr = [] +arr.push({ val: 1, bar: 2 }); +foo(arr); diff --git a/tests/cases/compiler/declarationEmitExpressionInExtends6.ts b/tests/cases/compiler/declarationEmitExpressionInExtends6.ts new file mode 100644 index 0000000000000..876be6ded3c9b --- /dev/null +++ b/tests/cases/compiler/declarationEmitExpressionInExtends6.ts @@ -0,0 +1,15 @@ +// @module: commonjs +// @declaration: true +// @allowJs: true +// @types: node +// @currentDirectory: / + +// @Filename: /node_modules/@types/node/index.d.ts +declare const require: any; + +// @Filename: /a.js +export class Foo {} + +// @Filename: /b.ts +const { Foo } = require("./a"); +export default class extends Foo {} diff --git a/tests/cases/compiler/declarationEmitExpressionInExtends7.ts b/tests/cases/compiler/declarationEmitExpressionInExtends7.ts new file mode 100644 index 0000000000000..8ec46fe1524ae --- /dev/null +++ b/tests/cases/compiler/declarationEmitExpressionInExtends7.ts @@ -0,0 +1,2 @@ +// @declaration: true +export default class extends SomeUndefinedFunction {} diff --git a/tests/cases/compiler/doesNotNarrowUnionOfConstructorsWithInstanceof.ts b/tests/cases/compiler/doesNotNarrowUnionOfConstructorsWithInstanceof.ts new file mode 100644 index 0000000000000..be07d81d07e3c --- /dev/null +++ b/tests/cases/compiler/doesNotNarrowUnionOfConstructorsWithInstanceof.ts @@ -0,0 +1,26 @@ +class A { + length: 1 + constructor() { + this.length = 1 + } +} + +class B { + length: 2 + constructor() { + this.length = 2 + } +} + +function getTypedArray(flag: boolean) { + return flag ? new A() : new B(); +} +function getTypedArrayConstructor(flag: boolean) { + return flag ? A : B; +} +const a = getTypedArray(true); // A | B +const b = getTypedArrayConstructor(false); // A constructor | B constructor + +if (!(a instanceof b)) { + console.log(a.length); // Used to be property 'length' does not exist on type 'never'. +} diff --git a/tests/cases/compiler/importHelpersWithExportStarAs.ts b/tests/cases/compiler/importHelpersWithExportStarAs.ts new file mode 100644 index 0000000000000..4dae5fca0a2c7 --- /dev/null +++ b/tests/cases/compiler/importHelpersWithExportStarAs.ts @@ -0,0 +1,14 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @filename: a.ts +export class A { } + +// @filename: b.ts +export * as a from "./a"; + +// @filename: tslib.d.ts +declare module "tslib" { + function __importStar(m: any): void; +} \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersWithImportOrExportDefault.ts b/tests/cases/compiler/importHelpersWithImportOrExportDefault.ts new file mode 100644 index 0000000000000..a314deaf1f24b --- /dev/null +++ b/tests/cases/compiler/importHelpersWithImportOrExportDefault.ts @@ -0,0 +1,17 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @filename: a.ts +export default class { } + +// @filename: b.ts +export { default } from "./a"; +export { default as a } from "./a"; +import { default as b } from "./a"; +void b; + +// @filename: tslib.d.ts +declare module "tslib" { + function __importDefault(m: any): void; +} \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.1.ts b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.1.ts new file mode 100644 index 0000000000000..f8d5639d277ba --- /dev/null +++ b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.1.ts @@ -0,0 +1,11 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @noEmit: true +// @noTypesAndSymbols: true +// @filename: a.ts +export default class { } + +// @filename: b.ts +export { default } from "./a"; diff --git a/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.2.ts b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.2.ts new file mode 100644 index 0000000000000..66d99d7cd8305 --- /dev/null +++ b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.2.ts @@ -0,0 +1,11 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @noEmit: true +// @noTypesAndSymbols: true +// @filename: a.ts +export default class { } + +// @filename: b.ts +export { default as a } from "./a"; diff --git a/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.3.ts b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.3.ts new file mode 100644 index 0000000000000..f8c2fdafc9fc1 --- /dev/null +++ b/tests/cases/compiler/importHelpersWithImportOrExportDefaultNoTslib.3.ts @@ -0,0 +1,12 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @noEmit: true +// @noTypesAndSymbols: true +// @filename: a.ts +export default class { } + +// @filename: b.ts +import { default as b } from "./a"; +void b; diff --git a/tests/cases/compiler/importHelpersWithImportStarAs.ts b/tests/cases/compiler/importHelpersWithImportStarAs.ts new file mode 100644 index 0000000000000..e4e97c35381ec --- /dev/null +++ b/tests/cases/compiler/importHelpersWithImportStarAs.ts @@ -0,0 +1,15 @@ +// @importHelpers: true +// @target: es2017 +// @module: commonjs,system,amd,es2015,es2020 +// @esModuleInterop: true,false +// @filename: a.ts +export class A { } + +// @filename: b.ts +import * as a from "./a"; +export { a }; + +// @filename: tslib.d.ts +declare module "tslib" { + function __importStar(m: any): void; +} \ No newline at end of file diff --git a/tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx b/tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx index c509ed5b46103..06e807100957a 100644 --- a/tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx +++ b/tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx @@ -3,6 +3,7 @@ //@jsxFragmentFactory: Frag declare var h: any; +declare var Frag: any; <>; <>1<>2.12.2; \ No newline at end of file diff --git a/tests/cases/compiler/jsxFragmentFactoryNoUnusedLocals.tsx b/tests/cases/compiler/jsxFragmentFactoryNoUnusedLocals.tsx new file mode 100644 index 0000000000000..db32bd99894da --- /dev/null +++ b/tests/cases/compiler/jsxFragmentFactoryNoUnusedLocals.tsx @@ -0,0 +1,18 @@ +// @jsx: react +// @jsxFactory: createElement +// @jsxFragmentFactory: Fragment +// @noUnusedLocals: true +/// +import { Fragment, createElement } from "react" + +type CounterProps = { + count?: number +} + +export function Counter({ count = 0 }: CounterProps) { + const [cnt, setCnt] = null as any; + return <> +

{cnt}

+ + +} \ No newline at end of file diff --git a/tests/cases/compiler/moduleResolutionWithRequire.ts b/tests/cases/compiler/moduleResolutionWithRequire.ts new file mode 100644 index 0000000000000..1ff915cbf6dd8 --- /dev/null +++ b/tests/cases/compiler/moduleResolutionWithRequire.ts @@ -0,0 +1,11 @@ +// @traceResolution: true + +// @filename: /other.ts +export const other = 123; + +// @filename: /index.ts +declare const require: any; +function foo() { + const a = require('../outside-of-rootdir/foo'); + const { other }: { other: string } = require('./other'); +} diff --git a/tests/cases/compiler/moduleResolutionWithRequireAndImport.ts b/tests/cases/compiler/moduleResolutionWithRequireAndImport.ts new file mode 100644 index 0000000000000..8225f69fe9f2e --- /dev/null +++ b/tests/cases/compiler/moduleResolutionWithRequireAndImport.ts @@ -0,0 +1,12 @@ +// @traceResolution: true + +// @filename: /other.ts +export const other = 123; + +// @filename: /index.ts +declare const require: any; +const a: typeof import('./other') = null as any +function foo() { + const a = require('../outside-of-rootdir/foo'); + const { other }: { other: string } = require('./other'); +} diff --git a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts index a9b11e29034f4..f550bd7bb4d0f 100644 --- a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts +++ b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts @@ -93,3 +93,9 @@ let rover: Dog = { bark() {} }; declare let map: MyMap; map[rover] = "Rover"; + +interface I { + prop: MyMap +} +declare const m: I; +m.prop['a']; diff --git a/tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts b/tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts new file mode 100644 index 0000000000000..e6ff1a3d5035d --- /dev/null +++ b/tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts @@ -0,0 +1,3 @@ +type N = T | { [P in K]: N }[K]; + +type M = N; \ No newline at end of file diff --git a/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts b/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts new file mode 100644 index 0000000000000..48cf12239caf7 --- /dev/null +++ b/tests/cases/compiler/spreadObjectWithIndexDoesNotAddUndefinedToLocalIndex.ts @@ -0,0 +1,3 @@ +// @strict: true +declare const m: { [k: string]: string }; +const x: { [k: string]: string } = { ...m, ["a" + "b"]: "" }; \ No newline at end of file diff --git a/tests/cases/compiler/templateLiteralsAndDecoratorMetadata.ts b/tests/cases/compiler/templateLiteralsAndDecoratorMetadata.ts new file mode 100644 index 0000000000000..f9c3ea2600385 --- /dev/null +++ b/tests/cases/compiler/templateLiteralsAndDecoratorMetadata.ts @@ -0,0 +1,7 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +declare var format: any; +export class Greeter { + @format("Hello, %s") + greeting: `boss` | `employee` = `employee`; //template literals on this line cause the issue +} \ No newline at end of file diff --git a/tests/cases/compiler/tryCatchFinallyControlFlow.ts b/tests/cases/compiler/tryCatchFinallyControlFlow.ts index 83909b5ddb035..c2f19bbe5bbc9 100644 --- a/tests/cases/compiler/tryCatchFinallyControlFlow.ts +++ b/tests/cases/compiler/tryCatchFinallyControlFlow.ts @@ -259,3 +259,73 @@ function t1() { })(); x; // Reachable } + +// Repro from #39043 + +type State = { tag: "one" } | { tag: "two" } | { tag: "three" }; + +function notallowed(arg: number) { + let state: State = { tag: "one" }; + try { + state = { tag: "two" }; + try { + state = { tag: "three" }; + } + finally { } + } + catch (err) { + state.tag; + if (state.tag !== "one" && state.tag !== "two") { + console.log(state.tag); + } + } +} + +function f20() { + let x: 0 | 1 | 2 | 3 | 4 | 5 | 6 = 0; + try { + x = 1; + try { + x = 2; + try { + x = 3; + } + finally { + if (!!true) x = 4; + } + x; // 3 | 4 + } + finally { + if (!!true) x = 5; + } + x; // 3 | 4 | 5 + } + finally { + if (!!true) x = 6; + } + x; // 3 | 4 | 5 | 6 +} + +function f21() { + let x: 0 | 1 | 2 | 3 | 4 | 5 = 0; + try { + x = 1; + try { + x = 2; + try { + x = 3; + } + finally { + if (!!true) x = 4; + } + x; // 3 | 4 + } + finally { + if (!!true) x = 5; + } + x; // 3 | 4 | 5 + } + catch (e) { + x; // 0 | 1 | 2 | 3 | 4 | 5 + } +} diff --git a/tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts b/tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts new file mode 100644 index 0000000000000..0c24b47804fa8 --- /dev/null +++ b/tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts @@ -0,0 +1,25 @@ +type U1 = string | new () => void; +type U2 = string | new (foo: number) => void +type U3 = | new () => number +type U4 = | new (foo?: number) => void; +type U5 = string | new (number: number, foo?: string) => void | number; +type U6 = + | string + | new (...args: any[]) => void + | number; + +type I1 = string & new () => void; +type I2 = string & new (...foo: number[]) => void; +type I3 = & new () => boolean +type I4 = & new () => boolean & null; +type I5 = string & new (any: any, any2: any) => any & any; +type I6 = + & string + & new (foo: any) => void; + +type M1 = string | number & string | new () => number; +type M2 = any & string | any & new () => void; +type M3 = any & new (foo: any) => void | new () => void & any; + +type OK1 = string | (new ()=> void); +type OK2 = string | (new ()=> string | number); diff --git a/tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts b/tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts new file mode 100644 index 0000000000000..861f7e8cc2020 --- /dev/null +++ b/tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts @@ -0,0 +1,27 @@ +type U1 = string | () => void; +type U2 = string | (foo: number) => void +type U3 = | () => number +type U4 = | (foo?: number) => void; +type U5 = string | (number: number, foo?: string) => void | number; +type U6 = + | string + | (...args: any[]) => void + | number; + +type I1 = string & () => void; +type I2 = string & (...foo: number[]) => void; +type I3 = & () => boolean +type I4 = & () => boolean & null; +type I5 = string & (any: any, any2: any) => any & any; +type I6 = + & string + & (foo: any) => void; + +type M1 = string | number & string | () => number; +type M2 = any & string | any & () => void; +type M3 = any & (foo: any) => void | () => void & any; + +type OK1 = string | (number); +type OK2 = string | ((number)); +type OK3 = string | (()=> void); +type OK4 = string | (()=> string | number); diff --git a/tests/cases/conformance/decorators/decoratorMetadataWithTypeOnlyImport.ts b/tests/cases/conformance/decorators/decoratorMetadataWithTypeOnlyImport.ts new file mode 100644 index 0000000000000..e0f26d0518c44 --- /dev/null +++ b/tests/cases/conformance/decorators/decoratorMetadataWithTypeOnlyImport.ts @@ -0,0 +1,21 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @target: es5 +// @module: commonjs +// @filename: service.ts +export class Service { +} +// @filename: component.ts +import type { Service } from "./service"; + +declare var decorator: any; + +@decorator +class MyComponent { + constructor(public Service: Service) { + } + + @decorator + method(x: this) { + } +} \ No newline at end of file diff --git a/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts b/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts index 5ace102ce56a4..2e6055754433b 100644 --- a/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts +++ b/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts @@ -1,5 +1,6 @@ // @module: commonjs // @importHelpers: true +// @esModuleInterop: true // @noTypesAndSymbols: true // @Filename: a.ts diff --git a/tests/cases/conformance/jsdoc/constructorTagWithThisTag.ts b/tests/cases/conformance/jsdoc/constructorTagWithThisTag.ts new file mode 100644 index 0000000000000..0483ca0a8b439 --- /dev/null +++ b/tests/cases/conformance/jsdoc/constructorTagWithThisTag.ts @@ -0,0 +1,13 @@ +// @allowJs: true +// @noEmit: true +// @checkJs: true +// @Filename: classthisboth.js + +/** + * @class + * @this {{ e: number, m: number }} + * this-tag should win, both 'e' and 'm' should be defined. + */ +function C() { + this.e = this.m + 1 +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassStaticMethodAugmentation.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassStaticMethodAugmentation.ts new file mode 100644 index 0000000000000..ff8b56c3ec2fd --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassStaticMethodAugmentation.ts @@ -0,0 +1,11 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: source.js +export class Clazz { + static method() { } +} + +Clazz.method.prop = 5; \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsConstsAsNamespacesWithReferences.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsConstsAsNamespacesWithReferences.ts new file mode 100644 index 0000000000000..8534d9e563ea3 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsConstsAsNamespacesWithReferences.ts @@ -0,0 +1,13 @@ +// @allowJs: true +// @checkJs: true +// @outDir: ./out +// @target: es6 +// @declaration: true +// @filename: index.js +export const colors = { + royalBlue: "#6400e4", +}; + +export const brandColors = { + purple: colors.royalBlue, +}; \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/jsdocFunctionType.ts b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts index 95c8f8966f19c..48875d52c81f7 100644 --- a/tests/cases/conformance/jsdoc/jsdocFunctionType.ts +++ b/tests/cases/conformance/jsdoc/jsdocFunctionType.ts @@ -70,3 +70,15 @@ var E = function(n) { var y3 = id2(E); + +// Repro from #39229 + +/** + * @type {(...args: [string, string] | [number, string, string]) => void} + */ +function foo(...args) { + args; +} + +foo('abc', 'def'); +foo(42, 'abc', 'def'); diff --git a/tests/cases/conformance/jsdoc/jsdocParseStarEquals.ts b/tests/cases/conformance/jsdoc/jsdocParseStarEquals.ts index e5f07bb3d2f6d..ef93965e0fc87 100644 --- a/tests/cases/conformance/jsdoc/jsdocParseStarEquals.ts +++ b/tests/cases/conformance/jsdoc/jsdocParseStarEquals.ts @@ -12,3 +12,8 @@ function f(...args) { /** @type *= */ var x; + + +/** @param {function():*=} f */ +function cbf(f) { +} diff --git a/tests/cases/conformance/jsdoc/paramTagTypeResolution2.ts b/tests/cases/conformance/jsdoc/paramTagTypeResolution2.ts new file mode 100644 index 0000000000000..a1cd30426b7a4 --- /dev/null +++ b/tests/cases/conformance/jsdoc/paramTagTypeResolution2.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: 38572.js + +/** + * @template T + * @param {T} a + * @param {{[K in keyof T]: (value: T[K]) => void }} b + */ +function f(a, b) { +} + +f({ x: 42 }, { x(param) { param.toFixed() } }); diff --git a/tests/cases/conformance/salsa/assignmentToVoidZero1.ts b/tests/cases/conformance/salsa/assignmentToVoidZero1.ts new file mode 100644 index 0000000000000..b4911c98d2bfc --- /dev/null +++ b/tests/cases/conformance/salsa/assignmentToVoidZero1.ts @@ -0,0 +1,11 @@ +// @filename: assignmentToVoidZero1.js +// @declaration: true +// @module: commonjs +// @outdir: auss +// @checkJs: true +// @allowJs: true + +// #38552 +exports.y = exports.x = void 0; +exports.x = 1; +exports.y = 2; diff --git a/tests/cases/conformance/salsa/assignmentToVoidZero2.ts b/tests/cases/conformance/salsa/assignmentToVoidZero2.ts new file mode 100644 index 0000000000000..6820076ee5f3b --- /dev/null +++ b/tests/cases/conformance/salsa/assignmentToVoidZero2.ts @@ -0,0 +1,24 @@ +// @filename: assignmentToVoidZero2.js +// @declaration: true +// @module: commonjs +// @outdir: auss +// @checkJs: true +// @allowJs: true +// @noImplicitAny: true +exports.j = 1; +exports.k = void 0; +var o = {} +o.x = 1 +o.y = void 0 +o.x + o.y + +function C() { + this.p = 1 + this.q = void 0 +} +var c = new C() +c.p + c.q + +// @filename: importer.js +import { j, k } from './assignmentToVoidZero2' +j + k diff --git a/tests/cases/conformance/salsa/expandoOnAlias.ts b/tests/cases/conformance/salsa/expandoOnAlias.ts new file mode 100644 index 0000000000000..1a2ecb09f8170 --- /dev/null +++ b/tests/cases/conformance/salsa/expandoOnAlias.ts @@ -0,0 +1,24 @@ +// @allowJs: true +// @checkJs: true +// @declaration: true +// @emitDeclarationOnly: true + +// @Filename: vue.js +export class Vue {} +export const config = { x: 0 }; + +// @Filename: test.js +import { Vue, config } from "./vue"; + +// Expando declarations aren't allowed on aliases. +Vue.config = {}; +new Vue(); + +// This is not an expando declaration; it's just a plain property assignment. +config.x = 1; + +// This is not an expando declaration; it works because non-strict JS allows +// loosey goosey assignment on objects. +config.y = {}; +config.x; +config.y; diff --git a/tests/cases/conformance/salsa/unannotatedParametersAreOptional.ts b/tests/cases/conformance/salsa/unannotatedParametersAreOptional.ts new file mode 100644 index 0000000000000..d64261a572eef --- /dev/null +++ b/tests/cases/conformance/salsa/unannotatedParametersAreOptional.ts @@ -0,0 +1,25 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: test.js + +function f(x) {} +f(); // Always been ok + +class C { + static m(x) {} + p = x => {} + m(x) {} +} + +C.m(); // Always been ok +new C().m(); // Regression #39261 +new C().p(); // Regression #39261 + +const obj = { + m(x) {}, + p: x => {} +}; + +obj.m(); // Always been ok +obj.p(); // Always been ok diff --git a/tests/cases/conformance/types/mapped/mappedTypeOverlappingStringEnumKeys.ts b/tests/cases/conformance/types/mapped/mappedTypeOverlappingStringEnumKeys.ts new file mode 100644 index 0000000000000..c1ebd4b382c3c --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypeOverlappingStringEnumKeys.ts @@ -0,0 +1,36 @@ +// #37859 + +enum TerrestrialAnimalTypes { + CAT = "cat", + DOG = "dog" +}; + +enum AlienAnimalTypes { + CAT = "cat", +}; + +type AnimalTypes = TerrestrialAnimalTypes | AlienAnimalTypes; + +interface TerrestrialCat { + type: TerrestrialAnimalTypes.CAT; + address: string; +} + +interface AlienCat { + type: AlienAnimalTypes.CAT + planet: string; +} + +type Cats = TerrestrialCat | AlienCat; + +type CatMap = { + [V in AnimalTypes]: Extract[] +}; + +const catMap: CatMap = { + cat: [ + { type: TerrestrialAnimalTypes.CAT, address: "" }, + { type: AlienAnimalTypes.CAT, planet: "" } + ], + dog: [] as never[] +}; diff --git a/tests/cases/conformance/types/tuple/variadicTuples1.ts b/tests/cases/conformance/types/tuple/variadicTuples1.ts index 036c65469c32f..2a34d06e2b0e1 100644 --- a/tests/cases/conformance/types/tuple/variadicTuples1.ts +++ b/tests/cases/conformance/types/tuple/variadicTuples1.ts @@ -334,3 +334,45 @@ call('hello', 32, (a, b) => 42); // Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure call(...sa, (...x) => 42); + +// No inference to ending optional elements (except with identical structure) + +declare function f20(args: [...T, number?]): T; + +function f21(args: [...U, number?]) { + let v1 = f20(args); // U + let v2 = f20(["foo", "bar"]); // [] + let v3 = f20(["foo", 42]); // [] +} + +declare function f22(args: [...T, number]): T; +declare function f22(args: [...T]): T; + +function f23(args: [...U, number]) { + let v1 = f22(args); // U + let v2 = f22(["foo", "bar"]); // [string, string] + let v3 = f22(["foo", 42]); // [string] +} + +// Repro from #39327 + +interface Desc
{ + readonly f: (...args: A) => T; + bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; +} + +declare const a: Desc<[string, number, boolean], object>; +const b = a.bind("", 1); // Desc<[boolean], object> + +// Repro from #39607 + +declare function getUser(id: string, options?: { x?: string }): string; + +declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; + +function callApi(method: (...args: [...T, object]) => U) { + return (...args: [...T]) => method(...args, {}); +} + +callApi(getUser); +callApi(getOrgUser); diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts index e264df259adee..bea0b5ef78ffb 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts @@ -190,4 +190,12 @@ namespace GH20889 { type: obj1.type }; } -} \ No newline at end of file +} + +// https://github.com/microsoft/TypeScript/issues/39357 +namespace GH39357 { + type A = ["a", number] | ["b", number] | ["c", string]; + type B = "a" | "b" | "c"; + declare const b: B; + const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""]; +} diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc23.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc23.ts new file mode 100644 index 0000000000000..55f9e53bd94f6 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc23.ts @@ -0,0 +1,32 @@ +/// +// @strict: true +/////** +//// * @typedef Foo +//// * @template L, R +//// */ +/////** +//// * @param {function(R): boolean} a +//// * @param {function(R): L} b +//// * @returns {function(R): Foo.} +//// * @template L, R +//// */ +////function foo(a, b) { +////} + +verify.codeFix({ + description: ts.Diagnostics.Annotate_with_type_from_JSDoc.message, + index: 2, + newFileContent: +`/** + * @typedef Foo + * @template L, R + */ +/** + * @param {function(R): boolean} a + * @param {function(R): L} b + * @returns {function(R): Foo.} + * @template L, R + */ +function foo(a: (arg0: R) => boolean, b: (arg0: R) => L): (arg0: R) => Foo { +}`, +}); diff --git a/tests/cases/fourslash/codeFixAmbientClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixAmbientClassExtendAbstractMethod.ts index 35da0b24faa8e..7f854405d2fb8 100644 --- a/tests/cases/fourslash/codeFixAmbientClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixAmbientClassExtendAbstractMethod.ts @@ -5,19 +5,27 @@ //// abstract f(a: number, b: string): this; //// abstract f(a: string, b: number): Function; //// abstract f(a: string): Function; +//// +//// abstract f1(this: A): number; +//// abstract f2(this: A, a: number, b: string): number; +//// //// abstract foo(): number; ////} //// ////declare class C extends A {} verify.codeFix({ - description: "Implement inherited abstract class", + description: ts.Diagnostics.Implement_inherited_abstract_class.message, newFileContent: `abstract class A { abstract f(a: number, b: string): boolean; abstract f(a: number, b: string): this; abstract f(a: string, b: number): Function; abstract f(a: string): Function; + + abstract f1(this: A): number; + abstract f2(this: A, a: number, b: string): number; + abstract foo(): number; } @@ -26,6 +34,8 @@ declare class C extends A { f(a: number, b: string): this; f(a: string, b: number): Function; f(a: string): Function; + f1(this: A): number; + f2(this: A, a: number, b: string): number; foo(): number; }` }); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts b/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts deleted file mode 100644 index 855d5acb76920..0000000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterface1_optionQuote.ts +++ /dev/null @@ -1,21 +0,0 @@ -/// - -////interface IFoo { -//// a: 'string'; -//// c: { d: 'string'; }; -////} -////class Foo implements IFoo {} - -verify.codeFix({ - description: [ts.Diagnostics.Implement_interface_0.message, "IFoo"], - newFileContent: -`interface IFoo { - a: 'string'; - c: { d: 'string'; }; -} -class Foo implements IFoo { - a: 'string'; - c: { d: 'string'; }; -}`, - preferences: { quotePreference: "single" } -}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports.ts index 3a08ffa5e5a2a..689c221127bb4 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports.ts @@ -14,7 +14,7 @@ ////import { B, C, D } from './types2'; //// ////export interface Base { -//// a: A; +//// a: Readonly & { kind: "a"; }; //// b(p1: C): D; ////} @@ -32,9 +32,9 @@ import A from './types1'; import { B, C, D } from './types2'; export class C implements Base { - a: A; + a: Readonly & { kind: 'a'; }; b(p1: C): D { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } }`, }); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports_typeOnly.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports_typeOnly.ts index 9f261a72c2aed..55103d11486e1 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports_typeOnly.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceAutoImports_typeOnly.ts @@ -36,7 +36,7 @@ import type { B, C, D } from './types2'; export class C implements Base { a: A; b(p1: C): D { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } }`, }); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_noUndefinedOnOptionalParameter.ts b/tests/cases/fourslash/codeFixClassImplementInterface_noUndefinedOnOptionalParameter.ts new file mode 100644 index 0000000000000..2d6626e50e898 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_noUndefinedOnOptionalParameter.ts @@ -0,0 +1,23 @@ +/// + +////interface IFoo { +//// bar(x?: number | string): void; +////} +//// +////class Foo implements IFoo { +////} + +//https://github.com/microsoft/TypeScript/issues/39458 +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "IFoo"], + newFileContent: +`interface IFoo { + bar(x?: number | string): void; +} + +class Foo implements IFoo { + bar(x?: string | number): void { + throw new Error("Method not implemented."); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_optionQuote.ts b/tests/cases/fourslash/codeFixClassImplementInterface_optionQuote.ts deleted file mode 100644 index 7fa6d8d9a9c97..0000000000000 --- a/tests/cases/fourslash/codeFixClassImplementInterface_optionQuote.ts +++ /dev/null @@ -1,20 +0,0 @@ -/// - -////interface I { -//// m(): void; -////} -////class C implements I {} - -verify.codeFix({ - description: "Implement interface 'I'", - newFileContent: -`interface I { - m(): void; -} -class C implements I { - m(): void { - throw new Error('Method not implemented.'); - } -}`, - preferences: { quotePreference: "single" } -}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto1.ts b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto1.ts new file mode 100644 index 0000000000000..9c0e5e111fb63 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto1.ts @@ -0,0 +1,32 @@ +/// + +// @filename: a.ts +////export interface I { +//// a(): void; +//// b(x: "x", y: "a" | "b"): "b"; +//// +//// c: "c"; +//// d: { e: "e"; }; +////} +// @filename: b.ts +////import { I } from "./a"; +////class Foo implements I {} + +goTo.file("b.ts") +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "I"], + index: 0, + newFileContent: +`import { I } from "./a"; +class Foo implements I { + a(): void { + throw new Error("Method not implemented."); + } + b(x: "x", y: "a" | "b"): "b" { + throw new Error("Method not implemented."); + } + c: "c"; + d: { e: "e"; }; +}`, + preferences: { quotePreference: "auto" } +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto2.ts b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto2.ts new file mode 100644 index 0000000000000..d38832e91c092 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceAuto2.ts @@ -0,0 +1,32 @@ +/// + +// @filename: a.ts +////export interface I { +//// a(): void; +//// b(x: 'x', y: 'a' | 'b'): 'b'; +//// +//// c: 'c'; +//// d: { e: 'e'; }; +////} +// @filename: b.ts +////import { I } from './a'; +////class Foo implements I {} + +goTo.file("b.ts") +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "I"], + index: 0, + newFileContent: +`import { I } from './a'; +class Foo implements I { + a(): void { + throw new Error('Method not implemented.'); + } + b(x: 'x', y: 'a' | 'b'): 'b' { + throw new Error('Method not implemented.'); + } + c: 'c'; + d: { e: 'e'; }; +}`, + preferences: { quotePreference: "auto" } +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceDouble.ts b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceDouble.ts new file mode 100644 index 0000000000000..2e048875b8b05 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceDouble.ts @@ -0,0 +1,34 @@ +/// + +////interface I { +//// a(): void; +//// b(x: "x", y: "a" | "b"): "b"; +//// +//// c: "c"; +//// d: { e: "e"; }; +////} +////class Foo implements I {} + +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "I"], + index: 0, + newFileContent: +`interface I { + a(): void; + b(x: "x", y: "a" | "b"): "b"; + + c: "c"; + d: { e: "e"; }; +} +class Foo implements I { + a(): void { + throw new Error("Method not implemented."); + } + b(x: "x", y: "a" | "b"): "b" { + throw new Error("Method not implemented."); + } + c: "c"; + d: { e: "e"; }; +}`, + preferences: { quotePreference: "double" } +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceSingle.ts b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceSingle.ts new file mode 100644 index 0000000000000..0367ec6daa11b --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_quotePreferenceSingle.ts @@ -0,0 +1,34 @@ +/// + +////interface I { +//// a(): void; +//// b(x: 'x', y: 'a' | 'b'): 'b'; +//// +//// c: 'c'; +//// d: { e: 'e'; }; +////} +////class Foo implements I {} + +verify.codeFix({ + description: [ts.Diagnostics.Implement_interface_0.message, "I"], + index: 0, + newFileContent: +`interface I { + a(): void; + b(x: 'x', y: 'a' | 'b'): 'b'; + + c: 'c'; + d: { e: 'e'; }; +} +class Foo implements I { + a(): void { + throw new Error('Method not implemented.'); + } + b(x: 'x', y: 'a' | 'b'): 'b' { + throw new Error('Method not implemented.'); + } + c: 'c'; + d: { e: 'e'; }; +}`, + preferences: { quotePreference: "single" } +}); diff --git a/tests/cases/fourslash/codeFixImplicitThis_js_all.ts b/tests/cases/fourslash/codeFixImplicitThis_js_all.ts index f99518afa1366..d442252b25423 100644 --- a/tests/cases/fourslash/codeFixImplicitThis_js_all.ts +++ b/tests/cases/fourslash/codeFixImplicitThis_js_all.ts @@ -5,10 +5,12 @@ // @noImplicitThis: true // @Filename: /a.js -////function f() { -//// this.x = 1; -////} ////class C { +//// q() { +//// function i() { +//// this; +//// } +//// } //// m() { //// function h() { //// this; @@ -20,13 +22,12 @@ verify.codeFixAll({ fixId: "fixImplicitThis", fixAllDescription: "Fix all implicit-'this' errors", newFileContent: -`/** - * @class - */ -function f() { - this.x = 1; -} -class C { +`class C { + q() { + const i = () => { + this; + } + } m() { const h = () => { this; diff --git a/tests/cases/fourslash/codeFixImplicitThis_js_classTag.ts b/tests/cases/fourslash/codeFixImplicitThis_js_classTag.ts deleted file mode 100644 index 52e7930b481d7..0000000000000 --- a/tests/cases/fourslash/codeFixImplicitThis_js_classTag.ts +++ /dev/null @@ -1,22 +0,0 @@ -/// - -// @allowJs: true -// @checkJs: true -// @noImplicitThis: true - -// @Filename: /a.js -////function f() { -//// this.x = 1; -////} - -verify.codeFix({ - description: "Add '@class' tag", - index: 0, - newFileContent: -`/** - * @class - */ -function f() { - this.x = 1; -}`, -}); diff --git a/tests/cases/fourslash/codeFixImplicitThis_js_classTag_addToComment.ts b/tests/cases/fourslash/codeFixImplicitThis_js_classTag_addToComment.ts deleted file mode 100644 index 9b684512568b3..0000000000000 --- a/tests/cases/fourslash/codeFixImplicitThis_js_classTag_addToComment.ts +++ /dev/null @@ -1,24 +0,0 @@ -/// - -// @allowJs: true -// @checkJs: true -// @noImplicitThis: true - -// @Filename: /a.js -/////** Doc */ -////function f() { -//// this.x = 1; -////} - -verify.codeFix({ - description: "Add '@class' tag", - index: 0, - newFileContent: -`/** - * Doc - * @class - */ -function f() { - this.x = 1; -}`, -}); diff --git a/tests/cases/fourslash/codeFixInferFromUsageContextualImport4.ts b/tests/cases/fourslash/codeFixInferFromUsageContextualImport4.ts index fbb6336a869b0..037bdc1121195 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageContextualImport4.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageContextualImport4.ts @@ -25,8 +25,8 @@ verify.codeFix({ index: 0, description: "Infer parameter types from usage", newFileContent: -`import { getEmail } from './getEmail'; -import { User, Settings } from './a'; +`import { User, Settings } from './a'; +import { getEmail } from './getEmail'; export function f(user: User, settings: Settings) { getEmail(user, settings); diff --git a/tests/cases/fourslash/codeFixPropertyAssignment1.ts b/tests/cases/fourslash/codeFixPropertyAssignment1.ts new file mode 100644 index 0000000000000..3745a91f7540a --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyAssignment1.ts @@ -0,0 +1,14 @@ +/// + +////const a = { +//// x/**/= 1 +////} + +verify.codeFix({ + description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"], + index: 0, + newFileContent: +`const a = { + x: 1 +}`, +}); diff --git a/tests/cases/fourslash/codeFixPropertyAssignment2.ts b/tests/cases/fourslash/codeFixPropertyAssignment2.ts new file mode 100644 index 0000000000000..233e612a9a054 --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyAssignment2.ts @@ -0,0 +1,14 @@ +/// + +////const a = { +//// x /**/= 1 +////} + +verify.codeFix({ + description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"], + index: 0, + newFileContent: +`const a = { + x: 1 +}`, +}); diff --git a/tests/cases/fourslash/codeFixPropertyAssignment3.ts b/tests/cases/fourslash/codeFixPropertyAssignment3.ts new file mode 100644 index 0000000000000..8346230588e22 --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyAssignment3.ts @@ -0,0 +1,18 @@ +/// + +////const a = { +//// x: 1, +//// y /**/= 1, +//// z: 1 +////} + +verify.codeFix({ + description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"], + index: 0, + newFileContent: +`const a = { + x: 1, + y: 1, + z: 1 +}`, +}); diff --git a/tests/cases/fourslash/codeFixPropertyAssignment_fixAll.ts b/tests/cases/fourslash/codeFixPropertyAssignment_fixAll.ts new file mode 100644 index 0000000000000..5cf54db26b1be --- /dev/null +++ b/tests/cases/fourslash/codeFixPropertyAssignment_fixAll.ts @@ -0,0 +1,34 @@ +/// + +////const a = { +//// x: 1, +//// y = 1, +//// z: 1 +////} +////const b = { +//// x = 1, +//// y: 1 +////} +////const c = { +//// x: 1, +//// y = 1 +////} + +verify.codeFixAll({ + fixAllDescription: "Switch each misused '=' to ':'", + fixId: "fixPropertyAssignment", + newFileContent: +`const a = { + x: 1, + y: 1, + z: 1 +} +const b = { + x: 1, + y: 1 +} +const c = { + x: 1, + y: 1 +}` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts index b9410c035835b..50f376f9889cb 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType.ts @@ -19,7 +19,7 @@ verify.codeFix({ description: [ts.Diagnostics.Declare_method_0.message, "foo"], index: 0, newFileContent: -`import { create, A } from "./a"; +`import { A, create } from "./a"; class B { bar() { create(args => this.foo(args)); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts index 4a7afe32b53df..a95ccbca1d109 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType1.ts @@ -25,8 +25,8 @@ verify.codeFix({ description: [ts.Diagnostics.Declare_method_0.message, "foo"], index: 0, newFileContent: -`import { create, B } from "./b"; -import { A } from "./a"; +`import { A } from "./a"; +import { B, create } from "./b"; class C { bar() { create(args => this.foo(args)); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts index 057558455348e..3a6da2fb9dd96 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs_importArgumentType2.ts @@ -31,9 +31,9 @@ verify.codeFix({ description: [ts.Diagnostics.Declare_method_0.message, "foo"], index: 0, newFileContent: -`import { create, C } from "./c"; +`import { A } from "./a"; import { B } from "./b"; -import { A } from "./a"; +import { C, create } from "./c"; class D { bar() { create(args => this.foo(args)); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete.ts index b169ffb884800..92585714eec94 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete.ts @@ -50,7 +50,7 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: `import { used1 } from "foo"; import { used2 } from "foo"; diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_js.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_js.ts index a6251ffb19dca..7920810cacf50 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_js.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_js.ts @@ -38,7 +38,7 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: `/** Parameter doc comment */ function f() {} diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_paramInFunction.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_paramInFunction.ts index 80b190700bffa..4a5fdc78bca00 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_paramInFunction.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_all_delete_paramInFunction.ts @@ -5,6 +5,6 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: "export {};\n", }); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_deleteWrite.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_deleteWrite.ts index 61ff1211c7c50..945f79bc0103c 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_deleteWrite.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_deleteWrite.ts @@ -14,7 +14,7 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: ` export class C { diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused.ts index 4f3f9a3e61ebb..71430d0a7bcff 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused.ts @@ -7,7 +7,7 @@ ////const { x, y } = o; verify.codeFix({ - description: "Remove destructuring", + description: ts.Diagnostics.Remove_unused_destructuring_declaration.message, newFileContent: `export {}; `, diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_all.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_all.ts index c9d4f62f2db36..5a16f374f34d1 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_all.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_all.ts @@ -12,11 +12,11 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: `const { a } = o; a; -export function f({ a }) { +export function f({ a }, { }) { a; }`, }); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_for.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_for.ts index 27103357d3dd9..fab0d1795cbdc 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_for.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_for.ts @@ -6,7 +6,7 @@ ////for (const { x } of o) {} verify.codeFix({ - description: "Remove destructuring", + description: ts.Diagnostics.Remove_unused_destructuring_declaration.message, newFileContent: `for (const {} of o) {}`, }); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_nested.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_nested.ts index 73fca1139289f..b830f5a90b569 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_nested.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_allUnused_nested.ts @@ -7,7 +7,7 @@ ////const { x: { a, b } } = o; verify.codeFix({ - description: "Remove destructuring", + description: ts.Diagnostics.Remove_unused_destructuring_declaration.message, newFileContent: `export {}; const { } = o;`, diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts index e07837060852b..e885054f35997 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts @@ -38,7 +38,7 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: `{ const { x } = o; diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements.ts new file mode 100644 index 0000000000000..060354a0422e5 --- /dev/null +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements.ts @@ -0,0 +1,17 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true + +////export function f({ x, y }, a) { +//// a; +////} + +verify.codeFix({ + description: [ts.Diagnostics.Remove_unused_declarations_for_Colon_0.message, "x, y"], + index: 0, + newFileContent: +`export function f({ }, a) { + a; +}`, +}); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_all.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_all.ts index a55e867634a76..16c9e6b481547 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_all.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_all.ts @@ -4,7 +4,7 @@ // @noUnusedParameters: true ////function f(a, b, { x, y }) { b; } -////f(0, 1, 2); +////f(0, 1, { x: 1, y: 1 }); //// ////class C { //// m(a, b, c) { b; } @@ -23,10 +23,10 @@ verify.codeFixAll({ fixId: "unusedIdentifier_delete", - fixAllDescription: "Delete all unused declarations", + fixAllDescription: ts.Diagnostics.Delete_all_unused_declarations.message, newFileContent: -`function f(b) { b; } -f(1); +`function f(b, { }) { b; } +f(1, { x: 1, y: 1 }); class C { m(b) { b; } diff --git a/tests/cases/fourslash/commentSelection1.ts b/tests/cases/fourslash/commentSelection1.ts new file mode 100644 index 0000000000000..d5a7846395594 --- /dev/null +++ b/tests/cases/fourslash/commentSelection1.ts @@ -0,0 +1,26 @@ +// Simple comment selection cases. + +//// let var1[| = 1; +//// let var2 = 2; +//// let var3 |]= 3; +//// +//// let var4[| = 4;|] +//// +//// let [||]var5 = 5; +//// +//// //let var6[| = 6; +//// //let var7 = 7; +//// //let var8 |]= 8; + +verify.commentSelection( + `//let var1 = 1; +//let var2 = 2; +//let var3 = 3; + +let var4/* = 4;*/ + +//let var5 = 5; + +////let var6 = 6; +////let var7 = 7; +////let var8 = 8;`); \ No newline at end of file diff --git a/tests/cases/fourslash/commentSelection2.ts b/tests/cases/fourslash/commentSelection2.ts new file mode 100644 index 0000000000000..31c56a60a2bb4 --- /dev/null +++ b/tests/cases/fourslash/commentSelection2.ts @@ -0,0 +1,29 @@ +// Common jsx insert comment. + +//@Filename: file.tsx +//// const a = +//// [| +//// |] +//// ; +//// const b = +//// {/**/} +//// {/**/} +//// ; +//// const c = [| +//// +//// +//// ; + +verify.commentSelection( + `const a = + {/**/} + {/**/} +; +const b = + {/**/} + {/**/} +; +//const c = +// +// +;`); \ No newline at end of file diff --git a/tests/cases/fourslash/completionJSDocNamePath.ts b/tests/cases/fourslash/completionJSDocNamePath.ts new file mode 100644 index 0000000000000..e15f70eaa472d --- /dev/null +++ b/tests/cases/fourslash/completionJSDocNamePath.ts @@ -0,0 +1,15 @@ +// @noLib: true + +/// + +// fix crash from #38407 + +//// /** +//// * @returns {modu/*1*/le:ControlFlow} +//// */ +//// export function cargo() { +//// } + +goTo.marker('1'); +verify.completions({ marker: "1", excludes: ["module", "ControlFlow"] }); + diff --git a/tests/cases/fourslash/completionListInheritedClassMembers.ts b/tests/cases/fourslash/completionListInheritedClassMembers.ts new file mode 100644 index 0000000000000..334374eab44d2 --- /dev/null +++ b/tests/cases/fourslash/completionListInheritedClassMembers.ts @@ -0,0 +1,43 @@ +/// + +// @filename: a.ts +////interface I { +//// m2(): void; +//// m3(): void; +////} +//// +////type T1 = I; +////export interface A1 extends T1 { +//// m1(): void; +////} +////export class A1 {} +//// +////type T2 = Partial +////export interface A2 extends T2 { +//// m1(): void; +////} +////export class A2 {} +//// +////type T3 = Pick +////export interface A3 extends T3 { +//// m1(): void; +////} +////export class A3 {} + +// @filename: b.ts +////import { A1, A2, A3 } from './a'; +////class B1 extends A1 { +//// /*1*/ +////} +////class B2 extends A2 { +//// /*2*/ +////} +////class B3 extends A3 { +//// /*3*/ +////} + +verify.completions( + { marker: "1", exact: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true }, + { marker: "2", exact: ["m1", "m2", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true }, + { marker: "3", exact: ["m1", "m3", ...completion.classElementKeywords], isNewIdentifierLocation: true } +); diff --git a/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts b/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts index 2e1fd6003ba14..610b4fc73cfa8 100644 --- a/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts +++ b/tests/cases/fourslash/completionsImport_default_alreadyExistedWithRename.ts @@ -25,7 +25,7 @@ verify.applyCodeActionFromCompletion("", { name: "foo", source: "/a", description: `Import default 'foo' from module "./a"`, - newFileContent: `import f_o_o from "./a"; -import foo from "./a"; + newFileContent: `import foo from "./a"; +import f_o_o from "./a"; f;`, }); diff --git a/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts b/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts index 8e1ec13df79f3..55ba68abedded 100644 --- a/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts +++ b/tests/cases/fourslash/completionsImport_named_addToNamedImports.ts @@ -26,6 +26,6 @@ verify.applyCodeActionFromCompletion("", { name: "foo", source: "/a", description: `Add 'foo' to existing import declaration from "./a"`, - newFileContent: `import { x, foo } from "./a"; + newFileContent: `import { foo, x } from "./a"; f;`, }); diff --git a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts index cb55f859cca06..59766f81fcf50 100644 --- a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts +++ b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts @@ -14,21 +14,21 @@ verify.completions({ marker: "", exact: [ { - name: "Test2", - text: "(alias) function Test2(): void\nimport Test2", - kind: "alias" + name: "Test2", + text: "(alias) function Test2(): void\nimport Test2", + kind: "alias" }, completion.globalThisEntry, completion.undefinedVarEntry, { - name: "Test1", - source: "/a", - sourceDisplay: "./a", - text: "function Test1(): void", - kind: "function", - kindModifiers: "export", - hasAction: true, - sortText: completion.SortText.AutoImportSuggestions + name: "Test1", + source: "/a", + sourceDisplay: "./a", + text: "function Test1(): void", + kind: "function", + kindModifiers: "export", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions }, ...completion.statementKeywordsWithTypes, ], @@ -39,6 +39,6 @@ verify.applyCodeActionFromCompletion("", { name: "Test1", source: "/a", description: `Add 'Test1' to existing import declaration from "./a"`, - newFileContent: `import { Test2, Test1 } from "./a"; + newFileContent: `import { Test1, Test2 } from "./a"; t`, }); diff --git a/tests/cases/fourslash/completionsImport_reExport_wrongName.ts b/tests/cases/fourslash/completionsImport_reExport_wrongName.ts index 4080fe5cdb7dd..1b386e3728862 100644 --- a/tests/cases/fourslash/completionsImport_reExport_wrongName.ts +++ b/tests/cases/fourslash/completionsImport_reExport_wrongName.ts @@ -46,8 +46,8 @@ verify.applyCodeActionFromCompletion("", { name: "y", source: "/index", description: `Import 'y' from module "."`, - newFileContent: `import { x } from "./a"; -import { y } from "."; + newFileContent: `import { y } from "."; +import { x } from "./a"; `, }); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts b/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts index 07ca6ea70d65b..6de9ff55ada5a 100644 --- a/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts +++ b/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts @@ -8,10 +8,8 @@ verify.codeFix({ description: "Convert function to an ES2015 class", newFileContent: -` -/** Doc */ +`/** Doc */ class C { constructor() { this.x = 0; } -} -`, +}`, }); diff --git a/tests/cases/fourslash/extract-const_jsxElement1.ts b/tests/cases/fourslash/extract-const_jsxElement1.ts new file mode 100644 index 0000000000000..3018aa0cadd09 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxElement1.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to constant in global scope", + newContent: +`const /*RENAME*/newLocal = ; +function Foo() { + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxElement2.ts b/tests/cases/fourslash/extract-const_jsxElement2.ts new file mode 100644 index 0000000000000..eb1bd23473a4a --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxElement2.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_0", + actionDescription: "Extract to constant in enclosing scope", + newContent: +`function Foo() { + const /*RENAME*/newLocal = ; + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxElement3.ts b/tests/cases/fourslash/extract-const_jsxElement3.ts new file mode 100644 index 0000000000000..ef9f9ff543411 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxElement3.ts @@ -0,0 +1,35 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to readonly field in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + private readonly newProperty = ; + + render() { + return ( +
+ {this./*RENAME*/newProperty} +
+ ); + } +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxFragment1.ts b/tests/cases/fourslash/extract-const_jsxFragment1.ts new file mode 100644 index 0000000000000..d67432f382ffd --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxFragment1.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to constant in global scope", + newContent: +`const /*RENAME*/newLocal = <>; +function Foo() { + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxFragment2.ts b/tests/cases/fourslash/extract-const_jsxFragment2.ts new file mode 100644 index 0000000000000..ba4a67bfa3862 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxFragment2.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_0", + actionDescription: "Extract to constant in enclosing scope", + newContent: +`function Foo() { + const /*RENAME*/newLocal = <>; + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxFragment3.ts b/tests/cases/fourslash/extract-const_jsxFragment3.ts new file mode 100644 index 0000000000000..8a5faf4457f14 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxFragment3.ts @@ -0,0 +1,35 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to readonly field in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + private readonly newProperty = <>; + + render() { + return ( +
+ {this./*RENAME*/newProperty} +
+ ); + } +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxSelfClosingElement1.ts b/tests/cases/fourslash/extract-const_jsxSelfClosingElement1.ts new file mode 100644 index 0000000000000..0a37c10763c12 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxSelfClosingElement1.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to constant in global scope", + newContent: +`const /*RENAME*/newLocal =
; +function Foo() { + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxSelfClosingElement2.ts b/tests/cases/fourslash/extract-const_jsxSelfClosingElement2.ts new file mode 100644 index 0000000000000..33dd2c6347b34 --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxSelfClosingElement2.ts @@ -0,0 +1,28 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_0", + actionDescription: "Extract to constant in enclosing scope", + newContent: +`function Foo() { + const /*RENAME*/newLocal =
; + return ( +
+ {newLocal} +
+ ); +}` +}); diff --git a/tests/cases/fourslash/extract-const_jsxSelfClosingElement3.ts b/tests/cases/fourslash/extract-const_jsxSelfClosingElement3.ts new file mode 100644 index 0000000000000..5d9569819aa0b --- /dev/null +++ b/tests/cases/fourslash/extract-const_jsxSelfClosingElement3.ts @@ -0,0 +1,35 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "constant_scope_1", + actionDescription: "Extract to readonly field in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + private readonly newProperty =
; + + render() { + return ( +
+ {this./*RENAME*/newProperty} +
+ ); + } +}` +}); diff --git a/tests/cases/fourslash/extract-method32.ts b/tests/cases/fourslash/extract-method32.ts index 229561e9795a1..d2d999fd290ad 100644 --- a/tests/cases/fourslash/extract-method32.ts +++ b/tests/cases/fourslash/extract-method32.ts @@ -21,7 +21,7 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to function in module scope", newContent: -`import { a, A } from "./a"; +`import { A, a } from "./a"; function foo() { const arg = a; diff --git a/tests/cases/fourslash/extract-method33.ts b/tests/cases/fourslash/extract-method33.ts index 96d4216c844d0..6c3adbd6d1808 100644 --- a/tests/cases/fourslash/extract-method33.ts +++ b/tests/cases/fourslash/extract-method33.ts @@ -29,8 +29,8 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to function in module scope", newContent: -`import { b, B } from "./b"; -import { A } from "./a"; +`import { A } from "./a"; +import { B, b } from "./b"; function foo() { const prop = b; diff --git a/tests/cases/fourslash/extract-method34.ts b/tests/cases/fourslash/extract-method34.ts index 7ffb72e7af54e..7499063268513 100644 --- a/tests/cases/fourslash/extract-method34.ts +++ b/tests/cases/fourslash/extract-method34.ts @@ -38,9 +38,9 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to function in module scope", newContent: -`import { c, C } from "./c"; +`import { A } from "./a"; import { B } from "./b"; -import { A } from "./a"; +import { C, c } from "./c"; function foo() { const prop = c; diff --git a/tests/cases/fourslash/extract-method35.ts b/tests/cases/fourslash/extract-method35.ts index 67a3edd0b4ad3..5f6ea76c6dabe 100644 --- a/tests/cases/fourslash/extract-method35.ts +++ b/tests/cases/fourslash/extract-method35.ts @@ -23,7 +23,7 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to method in class 'Foo'", newContent: -`import { a, A } from "./a"; +`import { A, a } from "./a"; class Foo { foo() { diff --git a/tests/cases/fourslash/extract-method36.ts b/tests/cases/fourslash/extract-method36.ts index 0b3e93e2b951a..47f9e75a24502 100644 --- a/tests/cases/fourslash/extract-method36.ts +++ b/tests/cases/fourslash/extract-method36.ts @@ -31,8 +31,8 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to method in class 'Foo'", newContent: -`import { b, B } from "./b"; -import { A } from "./a"; +`import { A } from "./a"; +import { B, b } from "./b"; class Foo { foo() { diff --git a/tests/cases/fourslash/extract-method37.ts b/tests/cases/fourslash/extract-method37.ts index 1f71cd098187b..c6a1c485cb63a 100644 --- a/tests/cases/fourslash/extract-method37.ts +++ b/tests/cases/fourslash/extract-method37.ts @@ -40,9 +40,9 @@ edit.applyRefactor({ actionName: "function_scope_1", actionDescription: "Extract to method in class 'Foo'", newContent: -`import { c, C } from "./c"; +`import { A } from "./a"; import { B } from "./b"; -import { A } from "./a"; +import { C, c } from "./c"; class Foo { foo() { diff --git a/tests/cases/fourslash/extract-method_jsxElement1.ts b/tests/cases/fourslash/extract-method_jsxElement1.ts new file mode 100644 index 0000000000000..1c5d2225a3d59 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxElement1.ts @@ -0,0 +1,32 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); +} + +function /*RENAME*/newFunction() { + return ; +} +` +}); diff --git a/tests/cases/fourslash/extract-method_jsxElement2.ts b/tests/cases/fourslash/extract-method_jsxElement2.ts new file mode 100644 index 0000000000000..d02b55e1c13a7 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxElement2.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_0", + actionDescription: "Extract to inner function in function 'Foo'", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); + + function /*RENAME*/newFunction() { + return ; + } +}` +}); diff --git a/tests/cases/fourslash/extract-method_jsxElement3.ts b/tests/cases/fourslash/extract-method_jsxElement3.ts new file mode 100644 index 0000000000000..7e0b4cc098ffc --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxElement3.ts @@ -0,0 +1,37 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*//*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + render() { + return ( +
+ {this./*RENAME*/newMethod()} +
+ ); + } + + private newMethod() { + return ; + } +}` +}); diff --git a/tests/cases/fourslash/extract-method_jsxFragment1.ts b/tests/cases/fourslash/extract-method_jsxFragment1.ts new file mode 100644 index 0000000000000..30a2426e01d04 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxFragment1.ts @@ -0,0 +1,32 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); +} + +function /*RENAME*/newFunction() { + return <>; +} +` +}); diff --git a/tests/cases/fourslash/extract-method_jsxFragment2.ts b/tests/cases/fourslash/extract-method_jsxFragment2.ts new file mode 100644 index 0000000000000..254924c51ee36 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxFragment2.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_0", + actionDescription: "Extract to inner function in function 'Foo'", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); + + function /*RENAME*/newFunction() { + return <>; + } +}` +}); diff --git a/tests/cases/fourslash/extract-method_jsxFragment3.ts b/tests/cases/fourslash/extract-method_jsxFragment3.ts new file mode 100644 index 0000000000000..e8983f6524d3c --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxFragment3.ts @@ -0,0 +1,37 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*/<>/*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + render() { + return ( +
+ {this./*RENAME*/newMethod()} +
+ ); + } + + private newMethod() { + return <>; + } +}` +}); diff --git a/tests/cases/fourslash/extract-method_jsxSelfClosingElement1.ts b/tests/cases/fourslash/extract-method_jsxSelfClosingElement1.ts new file mode 100644 index 0000000000000..041b4462bb6f0 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxSelfClosingElement1.ts @@ -0,0 +1,32 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); +} + +function /*RENAME*/newFunction() { + return
; +} +` +}); diff --git a/tests/cases/fourslash/extract-method_jsxSelfClosingElement2.ts b/tests/cases/fourslash/extract-method_jsxSelfClosingElement2.ts new file mode 100644 index 0000000000000..de96c61f8f728 --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxSelfClosingElement2.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////function Foo() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_0", + actionDescription: "Extract to inner function in function 'Foo'", + newContent: +`function Foo() { + return ( +
+ {newFunction()} +
+ ); + + function /*RENAME*/newFunction() { + return
; + } +}` +}); diff --git a/tests/cases/fourslash/extract-method_jsxSelfClosingElement3.ts b/tests/cases/fourslash/extract-method_jsxSelfClosingElement3.ts new file mode 100644 index 0000000000000..0b6f48253b96a --- /dev/null +++ b/tests/cases/fourslash/extract-method_jsxSelfClosingElement3.ts @@ -0,0 +1,37 @@ +/// + +// @jsx: preserve +// @filename: a.tsx +////declare var React: any; +////class Foo extends React.Component<{}, {}> { +//// render() { +//// return ( +////
+//// /*a*/
/*b*/ +////
+//// ); +//// } +////} + +goTo.file("a.tsx"); +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to method in class 'Foo'", + newContent: +`declare var React: any; +class Foo extends React.Component<{}, {}> { + render() { + return ( +
+ {this./*RENAME*/newMethod()} +
+ ); + } + + private newMethod() { + return
; + } +}` +}); diff --git a/tests/cases/fourslash/findAllReferencesUndefined.ts b/tests/cases/fourslash/findAllReferencesUndefined.ts new file mode 100644 index 0000000000000..f129b6d499074 --- /dev/null +++ b/tests/cases/fourslash/findAllReferencesUndefined.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: /a.ts +//// /**/undefined; +//// +//// void undefined; + +// @Filename: /b.ts +//// undefined; + +verify.baselineFindAllReferences(""); diff --git a/tests/cases/fourslash/findAllRefsForStaticInstanceMethodInheritance.ts b/tests/cases/fourslash/findAllRefsForStaticInstanceMethodInheritance.ts new file mode 100644 index 0000000000000..6e63cc63aad88 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsForStaticInstanceMethodInheritance.ts @@ -0,0 +1,37 @@ +/// + +////class X{ +//// [|[|{| "isDefinition": true, "contextRangeIndex": 0, "isWriteAccess": true |}foo|](): void{}|] +////} +//// +////class Y extends X{ +//// [|static [|{| "isDefinition": true, "contextRangeIndex": 2, "isWriteAccess": true |}foo|](): void{}|] +////} +//// +////class Z extends Y{ +//// [|static [|{| "isDefinition": true, "contextRangeIndex": 4, "isWriteAccess": true |}foo|](): void{}|] +//// [|[|{| "isDefinition": true, "contextRangeIndex": 6, "isWriteAccess": true |}foo|](): void{}|] +////} +//// +////const x = new X(); +////const y = new Y(); +////const z = new Z(); +////x.[|foo|](); +////y.[|foo|](); +////z.[|foo|](); +////Y.[|foo|](); +////Z.[|foo|](); + +const [r0Def, r0, r1Def, r1, r2Def, r2, r3Def, r3, r4, r5, r6, r7, r8] = test.ranges(); +verify.referenceGroups([r0, r3, r4, r5, r6], [ + { definition: { text: '(method) X.foo(): void', range: r0 }, ranges: [r0, r4, r5] }, + { definition: { text: '(method) Z.foo(): void', range: r3 }, ranges: [r3, r6] }, +]); + +verify.referenceGroups([r1, r7], [ + { definition: { text: '(method) Y.foo(): void', range: r1 }, ranges: [r1, r7] }, +]); + +verify.referenceGroups([r2, r8], [ + { definition: { text: '(method) Z.foo(): void', range: r2 }, ranges: [r2, r8] }, +]); diff --git a/tests/cases/fourslash/findAllRefsForStaticInstancePropertyInheritance.ts b/tests/cases/fourslash/findAllRefsForStaticInstancePropertyInheritance.ts new file mode 100644 index 0000000000000..62f2066ed9820 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsForStaticInstancePropertyInheritance.ts @@ -0,0 +1,37 @@ +/// + +////class X{ +//// [|[|{| "isDefinition": true, "contextRangeIndex": 0|}foo|]:any|] +////} +//// +////class Y extends X{ +//// [|static [|{| "isDefinition": true, "contextRangeIndex": 2|}foo|]:any|] +////} +//// +////class Z extends Y{ +//// [|static [|{| "isDefinition": true, "contextRangeIndex": 4|}foo|]:any|] +//// [|[|{| "isDefinition": true, "contextRangeIndex": 6|}foo|]:any|] +////} +//// +////const x = new X(); +////const y = new Y(); +////const z = new Z(); +////x.[|foo|]; +////y.[|foo|]; +////z.[|foo|]; +////Y.[|foo|]; +////Z.[|foo|]; + +const [r0Def, r0, r1Def, r1, r2Def, r2, r3Def, r3, r4, r5, r6, r7, r8] = test.ranges(); +verify.referenceGroups([r0, r3, r4, r5, r6], [ + { definition: { text: '(property) X.foo: any', range: r0 }, ranges: [r0, r4, r5] }, + { definition: { text: '(property) Z.foo: any', range: r3 }, ranges: [r3, r6] }, +]); + +verify.referenceGroups([r1, r7], [ + { definition: { text: '(property) Y.foo: any', range: r1 }, ranges: [r1, r7] }, +]); + +verify.referenceGroups([r2, r8], [ + { definition: { text: '(property) Z.foo: any', range: r2 }, ranges: [r2, r8] }, +]); diff --git a/tests/cases/fourslash/findAllRefsReExportStarAs.ts b/tests/cases/fourslash/findAllRefsReExportStarAs.ts new file mode 100644 index 0000000000000..a0392048ea8bf --- /dev/null +++ b/tests/cases/fourslash/findAllRefsReExportStarAs.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /leafModule.ts +////[|{| "id": "helloDecl" |}export const [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "helloDecl" |}hello|] = () => 'Hello';|] + +// @Filename: /exporting.ts +////[|{| "id": "leafExportDecl" |}export * as [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "leafExportDecl" |}Leaf|] from './leafModule';|] + +// @Filename: /importing.ts +//// [|{| "id": "leafImportDecl" |}import { [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "leafImportDecl" |}Leaf|] } from './exporting';|] +//// [|Leaf|].[|hello|]() + +verify.noErrors(); +const ranges = test.ranges(); +const [helloDecl, helloDef, leafExportDecl, leafDef, leafImportDecl, leafImportDef, leafUse, helloUse] = ranges; +verify.singleReferenceGroup("const hello: () => string", [helloDef, helloUse]); +const leafExportAsRef = { definition: "import Leaf", ranges: [leafDef] }; +const leafImportRef = { definition: "import Leaf", ranges: [leafImportDef, leafUse] }; +verify.referenceGroups([leafDef], [leafExportAsRef, leafImportRef]); +verify.referenceGroups([leafImportDef, leafUse], [leafImportRef, leafExportAsRef]); diff --git a/tests/cases/fourslash/formatCatch.ts b/tests/cases/fourslash/formatCatch.ts new file mode 100644 index 0000000000000..fce6cf75df57a --- /dev/null +++ b/tests/cases/fourslash/formatCatch.ts @@ -0,0 +1,16 @@ +/// + +////try { +////} /*0*/catch { +////} +//// +////try { +////} /*1*/catch{ +////} + +format.document(); + +for (const marker of test.markers()) { + goTo.marker(marker); + verify.currentLineContentIs("} catch {"); +} diff --git a/tests/cases/fourslash/formatTypeAnnotation1.ts b/tests/cases/fourslash/formatTypeAnnotation1.ts new file mode 100644 index 0000000000000..edd3a13ab9bc6 --- /dev/null +++ b/tests/cases/fourslash/formatTypeAnnotation1.ts @@ -0,0 +1,17 @@ +/// + +////function foo(x: number, y?: string): number {} +////interface Foo { +//// x: number; +//// y?: number; +////} + +format.setOption("insertSpaceBeforeTypeAnnotation", true); +format.document(); +verify.currentFileContentIs( +`function foo(x : number, y ?: string) : number { } +interface Foo { + x : number; + y ?: number; +}` +); diff --git a/tests/cases/fourslash/formatTypeAnnotation2.ts b/tests/cases/fourslash/formatTypeAnnotation2.ts new file mode 100644 index 0000000000000..a3708a6b66893 --- /dev/null +++ b/tests/cases/fourslash/formatTypeAnnotation2.ts @@ -0,0 +1,16 @@ +/// + +////function foo(x : number, y ?: string) : number {} +////interface Foo { +//// x : number; +//// y ?: number; +////} + +format.document(); +verify.currentFileContentIs( +`function foo(x: number, y?: string): number { } +interface Foo { + x: number; + y?: number; +}` +); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 3efb65d1251c7..f50cb18774415 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -289,6 +289,7 @@ declare namespace FourSlashInterface { goToType(startMarkerNames: ArrayOrSingle, endMarkerNames: ArrayOrSingle): void; verifyGetEmitOutputForCurrentFile(expected: string): void; verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void; + baselineFindAllReferences(markerName: string): void; noReferences(markerNameOrRange?: string | Range): void; symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void; typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void; @@ -397,6 +398,11 @@ declare namespace FourSlashInterface { generateTypes(...options: GenerateTypesOptions[]): void; organizeImports(newContent: string): void; + + toggleLineComment(newFileContent: string): void; + toggleMultilineComment(newFileContent: string): void; + commentSelection(newFileContent: string): void; + uncommentSelection(newFileContent: string): void; } class edit { backspace(count?: number): void; @@ -420,7 +426,7 @@ declare namespace FourSlashInterface { enableFormatting(): void; disableFormatting(): void; - applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string, newContent: NewFileContent }): void; + applyRefactor(options: { refactorName: string, actionName: string, actionDescription: string, newContent: NewFileContent, triggerReason?: RefactorTriggerReason }): void; } class debug { printCurrentParameterHelp(): void; @@ -592,7 +598,7 @@ declare namespace FourSlashInterface { filesToSearch?: ReadonlyArray; } interface UserPreferences { - readonly quotePreference?: "double" | "single"; + readonly quotePreference?: "auto" | "double" | "single"; readonly includeCompletionsForModuleExports?: boolean; readonly includeInsertTextCompletions?: boolean; readonly includeAutomaticOptionalChainCompletions?: boolean; @@ -644,6 +650,7 @@ declare namespace FourSlashInterface { isVariadic?: boolean; tags?: ReadonlyArray; triggerReason?: SignatureHelpTriggerReason; + overrideSelectedItemIndex?: number; } export type SignatureHelpTriggerReason = diff --git a/tests/cases/fourslash/getOutliningSpans.ts b/tests/cases/fourslash/getOutliningSpans.ts index bec0f4f0d3b29..f8bc10ad95544 100644 --- a/tests/cases/fourslash/getOutliningSpans.ts +++ b/tests/cases/fourslash/getOutliningSpans.ts @@ -106,14 +106,14 @@ ////function f(x: number[], y: number[])[| { //// return 3; ////}|] -////f( +////f[|( ////// single line array literal span won't render in VS //// [|[0]|], //// [|[ //// 1, //// 2 //// ]|] -////); +////)|]; verify.outliningSpansInCurrentFile(test.ranges(), "code"); diff --git a/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts b/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts index 9fc8c50dd7044..2dc01223c9a1d 100644 --- a/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts +++ b/tests/cases/fourslash/getOutliningSpansDepthChainedCalls.ts @@ -4,113 +4,113 @@ ////declare var router: any; ////router -//// .get("/", async(ctx) =>[|{ +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) -//// .get("/", async(ctx) =>[|{ +//// }|])|] +//// .get[|("/", async(ctx) =>[|{ //// ctx.body = "base"; -//// }|]) -//// .post("/a", async(ctx) =>[|{ +//// }|])|] +//// .post[|("/a", async(ctx) =>[|{ //// //a -//// }|]) +//// }|])|] verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport0.ts b/tests/cases/fourslash/importNameCodeFixExistingImport0.ts index e5b634998783c..922285e9afca3 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport0.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport0.ts @@ -7,4 +7,4 @@ //// export function f1() {} //// export var v1 = 5; -verify.importFixAtPosition([`{ v1, f1 }`]); +verify.importFixAtPosition([`{ f1, v1 }`]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport1.ts b/tests/cases/fourslash/importNameCodeFixExistingImport1.ts index 49680692b6c58..f06ce49f0ea6b 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport1.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport1.ts @@ -8,4 +8,4 @@ //// export var v1 = 5; //// export default var d1 = 6; -verify.importFixAtPosition([`{ v1, f1 }`]); +verify.importFixAtPosition([`{ f1, v1 }`]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport10.ts b/tests/cases/fourslash/importNameCodeFixExistingImport10.ts index a9525d272da00..3faa34deaa916 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport10.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport10.ts @@ -14,8 +14,8 @@ verify.importFixAtPosition([ `{ + f1, v1, - v2, - f1 + v2 }` ]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport11.ts b/tests/cases/fourslash/importNameCodeFixExistingImport11.ts index 786e0e397756e..4a414ef9a36de 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport11.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport11.ts @@ -14,8 +14,8 @@ verify.importFixAtPosition([ `{ + f1, v1, v2, - v3, - f1 + v3 }` ]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport6.ts b/tests/cases/fourslash/importNameCodeFixExistingImport6.ts index 0d3636e443955..7b2bd7d5383f5 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport6.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport6.ts @@ -10,4 +10,4 @@ //// export var v1 = 5; //// export function f1(); -verify.importFixAtPosition([`{ v1, f1 }`]); +verify.importFixAtPosition([`{ f1, v1 }`]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport7.ts b/tests/cases/fourslash/importNameCodeFixExistingImport7.ts index f0b1a77f69012..8a8ceb926c230 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport7.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport7.ts @@ -7,4 +7,4 @@ //// export var v1 = 5; //// export function f1(); -verify.importFixAtPosition([`{ v1, f1 }`]); +verify.importFixAtPosition([`{ f1, v1 }`]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport8.ts b/tests/cases/fourslash/importNameCodeFixExistingImport8.ts index a1b676a8b8309..a365136607d55 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport8.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport8.ts @@ -1,12 +1,12 @@ /// //// import [|{v1, v2, v3,}|] from "./module"; -//// f1/*0*/(); +//// v4/*0*/(); // @Filename: module.ts -//// export function f1() {} +//// export function v4() {} //// export var v1 = 5; //// export var v2 = 5; //// export var v3 = 5; -verify.importFixAtPosition([`{v1, v2, v3, f1,}`]); +verify.importFixAtPosition([`{v1, v2, v3, v4,}`]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImport9.ts b/tests/cases/fourslash/importNameCodeFixExistingImport9.ts index 67960de32d4c2..bc9701032bbeb 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImport9.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImport9.ts @@ -11,6 +11,7 @@ verify.importFixAtPosition([ `{ - v1, f1 + f1, + v1 }` ]); diff --git a/tests/cases/fourslash/importNameCodeFixExistingImportEquals0.ts b/tests/cases/fourslash/importNameCodeFixExistingImportEquals0.ts index de86ed13cd54b..4165cdae93bad 100644 --- a/tests/cases/fourslash/importNameCodeFixExistingImportEquals0.ts +++ b/tests/cases/fourslash/importNameCodeFixExistingImportEquals0.ts @@ -12,7 +12,7 @@ verify.importFixAtPosition([ `import ns = require("ambient-module"); var x = ns.v1 + 5;`, -`import ns = require("ambient-module"); -import { v1 } from "ambient-module"; +`import { v1 } from "ambient-module"; +import ns = require("ambient-module"); var x = v1 + 5;`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAmbient1.ts b/tests/cases/fourslash/importNameCodeFixNewImportAmbient1.ts index 835850306f68d..5966800667e7c 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportAmbient1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportAmbient1.ts @@ -1,8 +1,8 @@ /// //// import d from "other-ambient-module"; -//// [|import * as ns from "yet-another-ambient-module"; -//// var x = v1/*0*/ + 5;|] +//// import * as ns from "yet-another-ambient-module"; +//// var x = v1/*0*/ + 5; // @Filename: ambientModule.ts //// declare module "ambient-module" { @@ -22,7 +22,8 @@ //// } verify.importFixAtPosition([ -`import * as ns from "yet-another-ambient-module"; -import { v1 } from "ambient-module"; +`import { v1 } from "ambient-module"; +import d from "other-ambient-module"; +import * as ns from "yet-another-ambient-module"; var x = v1 + 5;` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportAmbient3.ts b/tests/cases/fourslash/importNameCodeFixNewImportAmbient3.ts index dbd6c4ef26ab8..0b596e455331d 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportAmbient3.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportAmbient3.ts @@ -2,8 +2,8 @@ //// let a = "I am a non-trivial statement that appears before imports"; //// import d from "other-ambient-module" -//// [|import * as ns from "yet-another-ambient-module" -//// var x = v1/*0*/ + 5;|] +//// import * as ns from "yet-another-ambient-module" +//// var x = v1/*0*/ + 5; // @Filename: ambientModule.ts //// declare module "ambient-module" { @@ -24,7 +24,9 @@ // test cases when there are no semicolons at the line end verify.importFixAtPosition([ -`import * as ns from "yet-another-ambient-module" +`let a = "I am a non-trivial statement that appears before imports"; import { v1 } from "ambient-module"; +import d from "other-ambient-module" +import * as ns from "yet-another-ambient-module" var x = v1 + 5;` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle0.ts b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle0.ts index 6b5ef958e0546..4a7f109c7b15a 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle0.ts @@ -11,8 +11,8 @@ //// export var v2 = 6; verify.importFixAtPosition([ -`import { v2 } from './module2'; -import { f1 } from './module1'; +`import { f1 } from './module1'; +import { v2 } from './module2'; f1();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle1.ts b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle1.ts index a9a12c419582e..ea131406ac25a 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle1.ts @@ -11,8 +11,8 @@ //// export var v2 = 6; verify.importFixAtPosition([ -`import { v2 } from "./module2"; -import { f1 } from "./module1"; +`import { f1 } from "./module1"; +import { v2 } from "./module2"; f1();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle2.ts b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle2.ts index c356e239ee86a..663670d63074a 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyle2.ts @@ -11,8 +11,8 @@ //// export var v2 = 6; verify.importFixAtPosition([ -`import m2 = require('./module2'); -import { f1 } from './module1'; +`import { f1 } from './module1'; +import m2 = require('./module2'); f1();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed0.ts b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed0.ts index 2f17780df7ff6..95e437bbe71ca 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed0.ts @@ -15,9 +15,9 @@ //// export var v3 = 6; verify.importFixAtPosition([ -`import { v2 } from "./module2"; +`import { f1 } from "./module1"; +import { v2 } from "./module2"; import { v3 } from './module3'; -import { f1 } from "./module1"; f1();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed1.ts b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed1.ts index ec68b3be0d844..310583671e38c 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportFileQuoteStyleMixed1.ts @@ -15,9 +15,9 @@ //// export var v3 = 6; verify.importFixAtPosition([ -`import { v2 } from './module2'; +`import { f1 } from './module1'; +import { v2 } from './module2'; import { v3 } from "./module3"; -import { f1 } from './module1'; f1();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts index 1beebb0477cd0..f94ecf1c75a47 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobal1.ts @@ -14,8 +14,8 @@ //// export as namespace bar1; verify.importFixAtPosition([ -`import { bar } from "./foo"; -import * as bar1 from "./foo"; +`import * as bar1 from "./foo"; +import { bar } from "./foo"; export function test() { }; bar1.bar();` diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts index 6fc3ce5498811..f630deb2a333e 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact0.ts @@ -29,8 +29,8 @@ goTo.file("/a.tsx"); verify.importFixAtPosition([ - `import { Component } from "react"; -import * as React from "react"; + `import * as React from "react"; +import { Component } from "react"; export class MyMap extends Component { } ;`]); @@ -38,6 +38,6 @@ export class MyMap extends Component { } goTo.file("/b.tsx"); verify.importFixAtPosition([ -`import { Component } from "react"; -import * as React from "react"; +`import * as React from "react"; +import { Component } from "react"; <>;`]); diff --git a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts index 9dba0f3988256..247b48e99cca7 100644 --- a/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts +++ b/tests/cases/fourslash/importNameCodeFixUMDGlobalReact1.ts @@ -25,7 +25,7 @@ goTo.file("/a.tsx"); verify.importFixAtPosition([ -`import { Component } from "react"; -import * as React from "react"; +`import * as React from "react"; +import { Component } from "react"; export class MyMap extends Component { } ;`]); diff --git a/tests/cases/fourslash/importNameCodeFix_all.ts b/tests/cases/fourslash/importNameCodeFix_all.ts index d5bb525900a6b..f76a5d1aa6950 100644 --- a/tests/cases/fourslash/importNameCodeFix_all.ts +++ b/tests/cases/fourslash/importNameCodeFix_all.ts @@ -37,10 +37,10 @@ verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", newFileContent: -`import bd, * as b from "./b"; +`import ad, { a0 } from "./a"; +import bd, * as b from "./b"; import cd, { c0 } from "./c"; import dd, { d0, d1 } from "./d"; -import ad, { a0 } from "./a"; import e = require("./e"); ad; ad; a0; a0; diff --git a/tests/cases/fourslash/importNameCodeFix_all2.ts b/tests/cases/fourslash/importNameCodeFix_all2.ts index 6f7a9b3403cdc..68c1e5d5106e8 100644 --- a/tests/cases/fourslash/importNameCodeFix_all2.ts +++ b/tests/cases/fourslash/importNameCodeFix_all2.ts @@ -15,8 +15,8 @@ goTo.file("/index.ts"); verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", - newFileContent: `import { join } from "./path"; -import { homedir } from "./os"; + newFileContent: `import { homedir } from "./os"; +import { join } from "./path"; join(); homedir();` diff --git a/tests/cases/fourslash/importNameCodeFix_avoidRelativeNodeModules.ts b/tests/cases/fourslash/importNameCodeFix_avoidRelativeNodeModules.ts index bff7fec290873..71a406a3b91c8 100644 --- a/tests/cases/fourslash/importNameCodeFix_avoidRelativeNodeModules.ts +++ b/tests/cases/fourslash/importNameCodeFix_avoidRelativeNodeModules.ts @@ -21,7 +21,7 @@ goTo.file("/c/foo.ts"); verify.importFixAtPosition([ -`import { b } from "b"; -import { a } from "a"; +`import { a } from "a"; +import { b } from "b"; a;`, ]); diff --git a/tests/cases/fourslash/importNameCodeFix_fileWithNoTrailingNewline.ts b/tests/cases/fourslash/importNameCodeFix_fileWithNoTrailingNewline.ts index 89d6398a5538b..f596de2691af7 100644 --- a/tests/cases/fourslash/importNameCodeFix_fileWithNoTrailingNewline.ts +++ b/tests/cases/fourslash/importNameCodeFix_fileWithNoTrailingNewline.ts @@ -13,7 +13,6 @@ goTo.file("/c.ts"); verify.importFixAtPosition([ `foo; -import { bar } from "./b"; import { foo } from "./a"; -`, +import { bar } from "./b";`, ]); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx.ts b/tests/cases/fourslash/importNameCodeFix_jsx1.ts similarity index 92% rename from tests/cases/fourslash/importNameCodeFix_jsx.ts rename to tests/cases/fourslash/importNameCodeFix_jsx1.ts index 5e09074ba1c75..27373611338e4 100644 --- a/tests/cases/fourslash/importNameCodeFix_jsx.ts +++ b/tests/cases/fourslash/importNameCodeFix_jsx1.ts @@ -33,6 +33,6 @@ import { Foo } from "./Foo"; // When JSX namespace is missing, provide fix for that goTo.file("/d.tsx"); verify.importFixAtPosition([ -`import { Foo } from "./Foo"; -import { React } from "react"; +`import { React } from "react"; +import { Foo } from "./Foo"; ;`]); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx2.ts b/tests/cases/fourslash/importNameCodeFix_jsx2.ts new file mode 100644 index 0000000000000..f740876ed7ec3 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx2.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////export = React; +////export as namespace React; +////declare namespace React { +//// class Component {} +////} + +// @Filename: /node_modules/react-native/index.d.ts +////import * as React from "react"; +////export class Text extends React.Component {}; + +// @Filename: /a.tsx +////import React from "react"; +////<[|Text|]>; + +goTo.file("/a.tsx"); +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"], + newFileContent: +`import React from "react"; +import { Text } from "react-native"; +;` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx3.ts b/tests/cases/fourslash/importNameCodeFix_jsx3.ts new file mode 100644 index 0000000000000..f889076734823 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx3.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////export = React; +////export as namespace React; +////declare namespace React { +//// class Component {} +////} + +// @Filename: /node_modules/react-native/index.d.ts +////import * as React from "react"; +////export class Text extends React.Component {}; + +// @Filename: /a.tsx +////import React from "react"; +////; + +goTo.file("/a.tsx"); +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"], + newFileContent: +`import React from "react"; +import { Text } from "react-native"; +;` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx4.ts b/tests/cases/fourslash/importNameCodeFix_jsx4.ts new file mode 100644 index 0000000000000..2303336d83cb2 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx4.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////export = React; +////export as namespace React; +////declare namespace React { +//// class Component {} +////} + +// @Filename: /node_modules/react-native/index.d.ts +////import * as React from "react"; +////export class Text extends React.Component {}; + +// @Filename: /a.tsx +////import { Text } from "react-native"; +////; + +goTo.file("/a.tsx"); +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_default_0_from_module_1.message, "React", "react"], + newFileContent: +`import React from "react"; +import { Text } from "react-native"; +;` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx5.ts b/tests/cases/fourslash/importNameCodeFix_jsx5.ts new file mode 100644 index 0000000000000..510175f375f82 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx5.ts @@ -0,0 +1,31 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////export = React; +////export as namespace React; +////declare namespace React { +//// class Component {} +////} + +// @Filename: /node_modules/react-native/index.d.ts +////import * as React from "react"; +////export class Text extends React.Component {}; + +// @Filename: /a.tsx +////import React from "react"; +////<[|Text|] />; + +goTo.file("/a.tsx"); +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"], + newFileContent: +`import React from "react"; +import { Text } from "react-native"; +;` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx6.ts b/tests/cases/fourslash/importNameCodeFix_jsx6.ts new file mode 100644 index 0000000000000..d98117fae67cf --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx6.ts @@ -0,0 +1,41 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////export = React; +////export as namespace React; +////declare namespace React { +//// class Component {} +////} + +// @Filename: /node_modules/react-native/index.d.ts +////import * as React from "react"; +////export class Text extends React.Component {}; + +// @Filename: /a.tsx +////<[|Text|]>; + +goTo.file("/a.tsx"); +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_default_0_from_module_1.message, "React", "react"], + applyChanges: true, + newFileContent: +`import React from "react"; + +;` +}); + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Import_0_from_module_1.message, "Text", "react-native"], + newFileContent: +`import React from "react"; +import { Text } from "react-native"; + +;` +}); diff --git a/tests/cases/fourslash/importNameCodeFix_jsx7.ts b/tests/cases/fourslash/importNameCodeFix_jsx7.ts new file mode 100644 index 0000000000000..545d7db76e798 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_jsx7.ts @@ -0,0 +1,15 @@ +/// + +// @jsx: react +// @module: esnext +// @esModuleInterop: true +// @moduleResolution: node + +// @Filename: /node_modules/react/index.d.ts +////// React was not defined + +// @Filename: /a.tsx +////<[|Text|]>; + +goTo.file("/a.tsx"); +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/importNameCodeFix_order.ts b/tests/cases/fourslash/importNameCodeFix_order.ts index 888b440e928ed..e4363a42997af 100644 --- a/tests/cases/fourslash/importNameCodeFix_order.ts +++ b/tests/cases/fourslash/importNameCodeFix_order.ts @@ -15,7 +15,7 @@ goTo.file("/c.ts"); verify.importFixAtPosition([ `import { bar, foo } from "./b"; foo;`, -`import { bar } from "./b"; -import { foo } from "./a"; +`import { foo } from "./a"; +import { bar } from "./b"; foo;`, ]); diff --git a/tests/cases/fourslash/importNameCodeFix_require.ts b/tests/cases/fourslash/importNameCodeFix_require.ts index c682c469246d4..74687bf3e3685 100644 --- a/tests/cases/fourslash/importNameCodeFix_require.ts +++ b/tests/cases/fourslash/importNameCodeFix_require.ts @@ -25,9 +25,9 @@ verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", newFileContent: -`const foo = require("./foo"); +`const { default: Blah } = require("./blah"); +const foo = require("./foo"); const { util1, util2 } = require("./utils"); -const { default: Blah } = require("./blah"); foo(); util1(); diff --git a/tests/cases/fourslash/importNameCodeFix_withJson.ts b/tests/cases/fourslash/importNameCodeFix_withJson.ts index 49d449b7b0498..cc6432402652d 100644 --- a/tests/cases/fourslash/importNameCodeFix_withJson.ts +++ b/tests/cases/fourslash/importNameCodeFix_withJson.ts @@ -9,7 +9,7 @@ ////a/**/ goTo.file("/b.ts"); -verify.importFixAtPosition([`import "./anything.json"; -import { a } from "./a"; +verify.importFixAtPosition([`import { a } from "./a"; +import "./anything.json"; a`]); diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion1.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion1.ts index a8e13edbe04de..5725870f0fbb5 100644 --- a/tests/cases/fourslash/jsdocDeprecated_suggestion1.ts +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion1.ts @@ -1,19 +1,22 @@ +/// +// @experimentalDecorators: true + // @Filename: a.ts //// export namespace foo { //// /** @deprecated */ //// export function faff () { } -//// [|faff|]() +//// [|faff()|] //// } -//// const [|a|] = foo.[|faff|]() +//// const [|a|] = [|foo.faff()|] //// foo[[|"faff"|]] //// const { [|faff|] } = foo -//// faff() +//// [|faff()|] //// /** @deprecated */ //// export function bar () { -//// foo?.[|faff|]() +//// [|foo?.faff()|] //// } -//// foo?.[[|"faff"|]]?.() -//// [|bar|](); +//// [|foo?.["faff"]?.()|] +//// [|bar()|]; //// /** @deprecated */ //// export interface Foo { //// /** @deprecated */ @@ -22,13 +25,52 @@ //// /** @deprecated */ //// export type QW = [|Foo|][[|"zzz"|]] //// export type WQ = [|QW|] +//// class C { +//// /** @deprecated */ +//// constructor() { +//// } +//// /** @deprecated */ +//// m() { } +//// } +//// /** @deprecated */ +//// class D { +//// constructor() { +//// } +//// } +//// var c = [|new C()|] +//// [|c.m()|] +//// c.[|m|] +//// new [|D|]() +//// C +//// [|D|] +// @Filename: j.tsx +//// type Props = { someProp?: any } +//// declare var props: Props +//// /** @deprecated */ +//// function Compi(_props: Props) { +//// return
+//// } +//// [|Compi|]; +//// [||]; +//// [||]
; +//// /** @deprecated */ +//// function ttf(_x: unknown) { +//// } +//// [|ttf``|] +//// [|ttf|] +//// /** @deprecated */ +//// function dec(_c: unknown) { } +//// [|dec|] +//// [|@dec|] +//// class K { } // @Filename: b.ts +//// // imports and aliases //// import * as f from './a'; //// import { [|bar|], [|QW|] } from './a'; -//// f.[|bar|](); -//// f.foo.[|faff|](); -//// [|bar|](); +//// [|f.bar()|]; +//// [|f.foo.faff()|]; +//// [|bar()|]; //// type Z = [|QW|]; //// type A = f.[|Foo|]; //// type B = f.[|QW|]; @@ -40,127 +82,214 @@ const ranges = test.ranges(); verify.getSuggestionDiagnostics([ { - message: "'faff' is deprecated", - code: 6385, - range: ranges[0], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[0] }, { - message: "'a' is declared but its value is never read.", - code: 6133, - range: ranges[1], - reportsUnnecessary: true + "code": 6133, + "message": "'a' is declared but its value is never read.", + "reportsUnnecessary": true, + "range": ranges[1] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[2], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[2] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[3], - reportsDeprecated: true, + "code": 6385, + "message": "'faff' is deprecated", + "reportsDeprecated": true, + "range": ranges[3] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[4], - reportsDeprecated: true, + "code": 6385, + "message": "'faff' is deprecated", + "reportsDeprecated": true, + "range": ranges[4] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[5], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[5] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[6], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[6] }, { - message: "'bar' is deprecated", - code: 6385, - range: ranges[7], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[7] }, { - message: "'Foo' is deprecated", - code: 6385, - range: ranges[8], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[8] }, { - message: "'zzz' is deprecated", - code: 6385, - range: ranges[9], - reportsDeprecated: true, + "code": 6385, + "message": "'Foo' is deprecated", + "reportsDeprecated": true, + "range": ranges[9] }, { - message: "'QW' is deprecated", - code: 6385, - range: ranges[10], - reportsDeprecated: true, - } -]) + "code": 6385, + "message": "'zzz' is deprecated", + "reportsDeprecated": true, + "range": ranges[10] + }, + { + "code": 6385, + "message": "'QW' is deprecated", + "reportsDeprecated": true, + "range": ranges[11] + }, + { + "code": 6385, + "message": "'(): C' is deprecated", + "reportsDeprecated": true, + "range": ranges[12] + }, + { + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[13] + }, + { + "code": 6385, + "message": "'m' is deprecated", + "reportsDeprecated": true, + "range": ranges[14] + }, + { + "code": 6385, + "message": "'D' is deprecated", + "reportsDeprecated": true, + "range": ranges[15] + }, + { + "code": 6385, + "message": "'D' is deprecated", + "reportsDeprecated": true, + "range": ranges[16] + }, +]); +goTo.file('j.tsx') +verify.getSuggestionDiagnostics([ + { + "code": 6385, + "message": "'Compi' is deprecated", + "reportsDeprecated": true, + "range": ranges[17] + }, + { + "code": 6385, + "message": "'(_props: Props): any' is deprecated", + "reportsDeprecated": true, + "range": ranges[18] + }, + { + "code": 6385, + "message": "'(_props: Props): any' is deprecated", + "reportsDeprecated": true, + "range": ranges[19] + }, + { + "code": 6385, + "message": "'Compi' is deprecated", + "reportsDeprecated": true, + "range": ranges[20] + }, + { + "code": 6385, + "message": "'(_x: unknown): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[21] + }, + { + "code": 6385, + "message": "'ttf' is deprecated", + "reportsDeprecated": true, + "range": ranges[22] + }, + { + "code": 6385, + "message": "'dec' is deprecated", + "reportsDeprecated": true, + "range": ranges[23] + }, + { + "code": 6385, + "message": "'(_c: unknown): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[24] + }, +]); goTo.file('b.ts') verify.getSuggestionDiagnostics([ { - message: "'bar' is deprecated", - code: 6385, - range: ranges[11], - reportsDeprecated: true, + "code": 6385, + "message": "'bar' is deprecated", + "reportsDeprecated": true, + "range": ranges[25] }, { - message: "'QW' is deprecated", - code: 6385, - range: ranges[12], - reportsDeprecated: true, + "code": 6385, + "message": "'QW' is deprecated", + "reportsDeprecated": true, + "range": ranges[26] }, { - message: "'bar' is deprecated", - code: 6385, - range: ranges[13], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[27] }, { - message: "'faff' is deprecated", - code: 6385, - range: ranges[14], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[28] }, { - message: "'bar' is deprecated", - code: 6385, - range: ranges[15], - reportsDeprecated: true, + "code": 6385, + "message": "'(): void' is deprecated", + "reportsDeprecated": true, + "range": ranges[29] }, { - message: "'QW' is deprecated", - code: 6385, - range: ranges[16], - reportsDeprecated: true, + "code": 6385, + "message": "'QW' is deprecated", + "reportsDeprecated": true, + "range": ranges[30] }, { - message: "'Foo' is deprecated", - code: 6385, - range: ranges[17], - reportsDeprecated: true, + "code": 6385, + "message": "'Foo' is deprecated", + "reportsDeprecated": true, + "range": ranges[31] }, { - message: "'QW' is deprecated", - code: 6385, - range: ranges[18], - reportsDeprecated: true, + "code": 6385, + "message": "'QW' is deprecated", + "reportsDeprecated": true, + "range": ranges[32] }, { - message: "'O' is declared but never used.", - code: 6196, - range: ranges[19], - reportsUnnecessary: true + "code": 6196, + "message": "'O' is declared but never used.", + "reportsUnnecessary": true, + "range": ranges[33] } -]) \ No newline at end of file +]) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion2.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion2.ts new file mode 100644 index 0000000000000..5f1560f08c238 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion2.ts @@ -0,0 +1,131 @@ +/// + +//// // overloads +//// declare function foo(a: string): number; +//// /** @deprecated */ +//// declare function foo(): undefined; +//// declare function foo (a?: string): number | undefined; +//// [|foo()|]; +//// foo(''); +//// foo; + +//// /** @deprecated */ +//// declare function bar(): number; +//// [|bar()|]; +//// [|bar|]; + +//// /** @deprecated */ +//// declare function baz(): number; +//// /** @deprecated */ +//// declare function baz(): number | undefined; +//// [|baz()|]; +//// [|baz|]; + +//// interface Foo { +//// /** @deprecated */ +//// (): void +//// (a: number): void +//// } +//// declare const f: Foo; +//// [|f()|]; +//// f(1); + +//// interface T { +//// createElement(): void +//// /** @deprecated */ +//// createElement(tag: 'xmp'): void; +//// } +//// declare const t: T; +//// t.createElement(); +//// [|t.createElement('xmp')|]; + +//// declare class C { +//// /** @deprecated */ +//// constructor (); +//// constructor(v: string) +//// } +//// C; +//// const c = [|new C()|]; + +//// interface Ca { +//// /** @deprecated */ +//// (): void +//// new (): void +//// } +//// interface Cb { +//// (): void +//// /** @deprecated */ +//// new (): string +//// } +//// declare const ca: Ca; +//// declare const cb: Cb; +//// ca; +//// cb; +//// [|ca()|]; +//// cb(); +//// new ca(); +//// [|new cb()|]; + +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + message: "'(): undefined' is deprecated", + code: 6385, + range: ranges[0], + reportsDeprecated: true, + }, + { + message: "'(): number' is deprecated", + code: 6385, + range: ranges[1], + reportsDeprecated: true, + }, + { + message: "'bar' is deprecated", + code: 6385, + range: ranges[2], + reportsDeprecated: true, + }, + { + message: "'(): number' is deprecated", + code: 6385, + range: ranges[3], + reportsDeprecated: true, + }, + { + message: "'baz' is deprecated", + code: 6385, + range: ranges[4], + reportsDeprecated: true, + }, + { + message: "'(): void' is deprecated", + code: 6385, + range: ranges[5], + reportsDeprecated: true, + }, + { + message: `'(tag: "xmp"): void' is deprecated`, + code: 6385, + range: ranges[6], + reportsDeprecated: true, + }, + { + message: `'(): C' is deprecated`, + code: 6385, + range: ranges[7], + reportsDeprecated: true, + }, + { + message: `'(): void' is deprecated`, + code: 6385, + range: ranges[8], + reportsDeprecated: true, + }, + { + message: `'(): string' is deprecated`, + code: 6385, + range: ranges[9], + reportsDeprecated: true, + }, +]) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion3.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion3.ts new file mode 100644 index 0000000000000..829060345fe22 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion3.ts @@ -0,0 +1,124 @@ +/// + +//// // merges +//// /** @deprecated */ +//// interface a { a: number } +//// declare function a(): void +//// declare const ta: [|a|] +//// a; +//// a(); + +//// interface b { a: number; } +//// /** @deprecated */ +//// declare function b(): void +//// declare const tb: b; +//// [|b|] +//// [|b()|]; + +//// interface c { } +//// /** @deprecated */ +//// declare function c(): void +//// declare function c(a: number): void +//// declare const tc: c; +//// c; +//// [|c()|]; +//// c(1); + +//// /** @deprecated */ +//// interface d { } +//// declare function d(): void +//// declare function d(a: number): void +//// declare const td: [|d|]; +//// d; +//// d(); +//// d(1); + +//// /** @deprecated */ +//// declare function e(): void +//// /** @deprecated */ +//// declare function e(a: number): void +//// [|e|]; +//// [|e()|]; +//// [|e(1)|]; + +//// /** @deprecated */ +//// interface f { a: number } +//// declare const tf: [|f|] + +//// /** @deprecated */ +//// type g = number +//// declare const tg: [|g|] + +//// /** @deprecated */ +//// class H { } +//// declare const th: [|H|] + +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + message: "'a' is deprecated", + code: 6385, + range: ranges[0], + reportsDeprecated: true, + }, + { + message: "'b' is deprecated", + code: 6385, + range: ranges[1], + reportsDeprecated: true, + }, + { + message: "'(): void' is deprecated", + code: 6385, + range: ranges[2], + reportsDeprecated: true, + }, + { + message: "'(): void' is deprecated", + code: 6385, + range: ranges[3], + reportsDeprecated: true, + }, + { + message: "'d' is deprecated", + code: 6385, + range: ranges[4], + reportsDeprecated: true, + }, + { + message: "'e' is deprecated", + code: 6385, + range: ranges[5], + reportsDeprecated: true, + }, + { + message: "'(): void' is deprecated", + code: 6385, + range: ranges[6], + reportsDeprecated: true, + }, + { + message: "'(a: number): void' is deprecated", + code: 6385, + range: ranges[7], + reportsDeprecated: true, + }, + { + message: "'f' is deprecated", + code: 6385, + range: ranges[8], + reportsDeprecated: true, + }, + { + message: "'g' is deprecated", + code: 6385, + range: ranges[9], + reportsDeprecated: true, + }, + { + message: "'H' is deprecated", + code: 6385, + range: ranges[10], + reportsDeprecated: true, + }, +]) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion4.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion4.ts new file mode 100644 index 0000000000000..9bcdf0de5e2b7 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion4.ts @@ -0,0 +1,50 @@ +/// + +//// interface Foo { +//// /** @deprecated */ +//// f: number +//// b: number +//// /** @deprecated */ +//// baz: number +//// } + +//// declare const f: Foo +//// f.[|f|]; +//// f.b; +//// f.[|baz|]; + +//// const kf = 'f' +//// const kb = 'b' +//// declare const k: 'f' | 'b' | 'baz' +//// declare const kfb: 'f' | 'b' +//// declare const kfz: 'f' | 'baz' +//// declare const keys: keyof Foo +//// f[[|kf|]] +//// f[kb] +//// f[k] +//// f[kfb] +//// f[kfz] +//// f[keys] + + +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + message: "'f' is deprecated", + code: 6385, + range: ranges[0], + reportsDeprecated: true, + }, + { + message: "'baz' is deprecated", + code: 6385, + range: ranges[1], + reportsDeprecated: true, + }, + { + message: "'f' is deprecated", + code: 6385, + range: ranges[2], + reportsDeprecated: true, + } +]) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion5.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion5.ts new file mode 100644 index 0000000000000..9693d291f1eb4 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion5.ts @@ -0,0 +1,23 @@ +/// + +// @checkJs: true +// @allowJs: true +// @Filename: jsdocDeprecated_suggestion5.js +//// /** @typedef {{ email: string, nickName?: string }} U2 */ +//// /** @type {U2} */ +//// const u2 = { email: "" } + +//// /** +//// * @callback K +//// * @param {any} ctx +//// * @return {void} +//// */ +//// /** @type {K} */ +//// const cc = _k => {} + +//// /** @enum {number} */ +//// const DOOM = { e: 1, m: 1 } +//// /** @type {DOOM} */ +//// const kneeDeep = DOOM.e + +verify.getSuggestionDiagnostics([]) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion6.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion6.ts new file mode 100644 index 0000000000000..6418da6e6c101 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion6.ts @@ -0,0 +1,46 @@ +// @Filename: a.tsx +//// /** @deprecated */ +//// type Props = {} + +//// /** @deprecated */ +//// const Component = (props: [|Props|]) => props &&
; + +//// <[|Component|] old="old" new="new" /> + +//// /** @deprecated */ +//// type Options = {} + +//// /** @deprecated */ +//// const deprecatedFunction = (options: [|Options|]) => { options } + +//// [|deprecatedFunction|]({}); + +goTo.file('a.tsx') +const ranges = test.ranges(); + +verify.getSuggestionDiagnostics([ + { + message: "'Props' is deprecated", + code: 6385, + range: ranges[0], + reportsDeprecated: true, + }, + { + message: "'Component' is deprecated", + code: 6385, + range: ranges[1], + reportsDeprecated: true + }, + { + message: "'Options' is deprecated", + code: 6385, + range: ranges[2], + reportsDeprecated: true, + }, + { + message: "'deprecatedFunction' is deprecated", + code: 6385, + range: ranges[3], + reportsDeprecated: true, + } +]) \ No newline at end of file diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion7.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion7.ts new file mode 100644 index 0000000000000..ff98ed0179f39 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion7.ts @@ -0,0 +1,14 @@ +/// + +//// enum Direction { +//// Left = -1, +//// Right = 1, +//// } +//// type T = Direction.Left + +//// /** @deprecated */ +//// const x = 1 +//// type x = string +//// var y: x = 'hi' + +verify.getSuggestionDiagnostics([]); diff --git a/tests/cases/fourslash/memberListInFunctionCall2.ts b/tests/cases/fourslash/memberListInFunctionCall2.ts new file mode 100644 index 0000000000000..5eb117b58f9cd --- /dev/null +++ b/tests/cases/fourslash/memberListInFunctionCall2.ts @@ -0,0 +1,17 @@ +/// + +////type T = { +//// a: 1; +//// b: 2; +////} +////function F(x: T) { +////} +////F({/*1*/} as const) + +verify.completions({ + marker: "1", + exact: [ + { name: "a", text: "(property) a: 1" }, + { name: "b", text: "(property) b: 2" }, + ], +}); diff --git a/tests/cases/fourslash/outliningSpansForArguments.ts b/tests/cases/fourslash/outliningSpansForArguments.ts new file mode 100644 index 0000000000000..56c3c21e77a8b --- /dev/null +++ b/tests/cases/fourslash/outliningSpansForArguments.ts @@ -0,0 +1,18 @@ +/// + +//// console.log(123, 456)l; +//// console.log( +//// ); +//// console.log[|( +//// 123, 456 +//// )|]; +//// console.log[|( +//// 123, +//// 456 +//// )|]; +//// () =>[| console.log[|( +//// 123, +//// 456 +//// )|]|]; + +verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts b/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts new file mode 100644 index 0000000000000..7dfc6e8ec2735 --- /dev/null +++ b/tests/cases/fourslash/outliningSpansForArrowFunctionBody.ts @@ -0,0 +1,15 @@ +/// + +//// () => 42; +//// () => ( 42 ); +//// () =>[| { +//// 42 +//// }|]; +//// () =>[| ( +//// 42 +//// )|]; +//// () =>[| "foo" + +//// "bar" + +//// "baz"|]; + +verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/outliningSpansForFunction.ts b/tests/cases/fourslash/outliningSpansForFunction.ts index f46886b73068d..e89ecd6f843ab 100644 --- a/tests/cases/fourslash/outliningSpansForFunction.ts +++ b/tests/cases/fourslash/outliningSpansForFunction.ts @@ -5,9 +5,9 @@ //// b: number ////) => { //// return a + b; -////}|] -///// -////(a: number, b: number) => [|{ +////}|]; +//// +////(a: number, b: number) =>[| { //// return a + b; ////}|] //// @@ -55,30 +55,30 @@ ////}|] //// ////declare function foo(props: any): void; -////foo( +////foo[|( //// a =>[| { //// //// }|] -////) +////)|] //// -////foo( +////foo[|( //// (a) =>[| { //// //// }|] -////) +////)|] //// -////foo( +////foo[|( //// (a, b, c) =>[| { //// //// }|] -////) +////)|] //// -////foo([| +////foo[|([| //// (a, //// b, //// c) => { //// //// }|] -////) +////)|] verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/quickfixImplementInterfaceUnreachableTypeUsesRelativeImport.ts b/tests/cases/fourslash/quickfixImplementInterfaceUnreachableTypeUsesRelativeImport.ts index 5db9047035513..d81500d489b33 100644 --- a/tests/cases/fourslash/quickfixImplementInterfaceUnreachableTypeUsesRelativeImport.ts +++ b/tests/cases/fourslash/quickfixImplementInterfaceUnreachableTypeUsesRelativeImport.ts @@ -18,8 +18,8 @@ verify.codeFix({ description: "Implement interface 'Foo'", newFileContent: { "/tests/cases/fourslash/index.ts": -`import { Foo } from './interface'; -import { Class } from './class'; +`import { Class } from './class'; +import { Foo } from './interface'; class X implements Foo { x: Class; diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallCallReturnValue.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallCallReturnValue.ts new file mode 100644 index 0000000000000..3336a71ed8360 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallCallReturnValue.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: () => { return () => { c: 0 } } } +/////*a*/a && a.b && a.b()().c/*b*/; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: () => { return () => { c: 0 } } } +a?.b?.()().c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallReturnValue.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallReturnValue.ts new file mode 100644 index 0000000000000..f4f2a6768aa04 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessCallReturnValue.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: () => { return { c: 0 } } } +/////*a*/a && a.b && a.b().c/*b*/; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: () => { return { c: 0 } } } +a?.b?.().c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessThenCall.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessThenCall.ts new file mode 100644 index 0000000000000..3e6f799604784 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_AccessThenCall.ts @@ -0,0 +1,12 @@ +/// + +/////*a*/a && a.b && a.b()/*b*/; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`a?.b?.();` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpression.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpression.ts new file mode 100644 index 0000000000000..400c84adb43e8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpression.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +/////*a*/a && a.b && a.b.c;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a?.b?.c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpressionPartialSpan.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpressionPartialSpan.ts new file mode 100644 index 0000000000000..1495cee31cbff --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryExpressionPartialSpan.ts @@ -0,0 +1,15 @@ +/// + +////let foo = { bar: { baz: 0 } }; +////f/*a*/oo && foo.bar && foo.bar.ba/*b*/z; + +// allow partial spans +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let foo = { bar: { baz: 0 } }; +foo?.bar?.baz;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryWithCallExpression.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryWithCallExpression.ts new file mode 100644 index 0000000000000..9385a0268b7cf --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_BinaryWithCallExpression.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: () => { } } }; +/////*a*/a && a.b && a.b.c();/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: () => { } } }; +a?.b?.c();` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_CallExpressionComparison.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_CallExpressionComparison.ts new file mode 100644 index 0000000000000..d9397ab11f2d8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_CallExpressionComparison.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: () => { } } }; +/////*a*/a && a.b && a.b.c() === 1;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: () => { } } }; +a?.b?.c() === 1;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ComparisonOperator.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ComparisonOperator.ts new file mode 100644 index 0000000000000..2e61bfea4da45 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ComparisonOperator.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +/////*a*/a && a.b && a.b.c === 1;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a?.b?.c === 1;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalForAny.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalForAny.ts new file mode 100644 index 0000000000000..cecca1a295e40 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalForAny.ts @@ -0,0 +1,16 @@ +/// + +// @strict: true + +////interface Foo { +//// bar?:{ +//// baz?: any; +//// } +////} +////declare let foo: Foo; +/////*a*/foo.bar ? foo.bar.baz : "whenFalse";/*b*/ + +// It is reasonable to offer a refactor when baz is of type any since implicit any in strict mode +// produces an error and those with strict mode off aren't getting null checks anyway. +goTo.select("a", "b"); +verify.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalInitialIdentifier.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalInitialIdentifier.ts new file mode 100644 index 0000000000000..7c73a2d2ee2e4 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalInitialIdentifier.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: 0 }; +/////*a*/a ? a.b : "whenFalse";/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: 0 }; +a?.b ?? "whenFalse";` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalNoNullish.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalNoNullish.ts new file mode 100644 index 0000000000000..eef8c58c84397 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalNoNullish.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true + +////interface Foo { +//// bar?:{ +//// baz?: string | null; +//// } +////} +////declare let foo: Foo; +/////*a*/foo.bar ? foo.bar.baz : "whenFalse";/*b*/ + +// do not offer a refactor for ternary expression if type of baz is nullish +goTo.select("a", "b"); +verify.not.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalPartialSPan.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalPartialSPan.ts new file mode 100644 index 0000000000000..e394527764325 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalPartialSPan.ts @@ -0,0 +1,15 @@ +/// + +////let foo = { bar: { baz: 0 } }; +////f/*a*/oo.bar ? foo.bar.baz : "when/*b*/False"; + +// allow partial spans +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let foo = { bar: { baz: 0 } }; +foo.bar?.baz ?? "whenFalse";` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalStrictMode.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalStrictMode.ts new file mode 100644 index 0000000000000..65f49e1ce459d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalStrictMode.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true + +////interface Foo { +//// bar?:{ +//// baz: string; +//// } +////} +////declare let foo: Foo; +/////*a*/foo.bar ? foo.bar.baz : "whenFalse";/*b*/ + +// Offer the refactor for ternary expressions if type of baz is not null, unknown, or undefined +goTo.select("a", "b"); +verify.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition1.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition1.ts new file mode 100644 index 0000000000000..5ddefb61d9c08 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition1.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +/////*a*/a && a.b/*b*/ ? a.b.c : "whenFalse"; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a?.b ? a.b.c : "whenFalse";` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition2.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition2.ts new file mode 100644 index 0000000000000..953f44a51bfc4 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryCondition2.ts @@ -0,0 +1,26 @@ +/// + +// @strict: true + +////interface Foo { +//// bar:{ +//// baz: string; +//// } +////} +////declare let foo: Foo; +/////*a*/foo && foo.bar ? foo.bar.baz : "whenFalse";/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`interface Foo { + bar:{ + baz: string; + } +} +declare let foo: Foo; +foo?.bar?.baz ?? "whenFalse";` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryConditionNoNullish.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryConditionNoNullish.ts new file mode 100644 index 0000000000000..e1c068e281003 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ConditionalWithBinaryConditionNoNullish.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true + +////interface Foo { +//// bar:{ +//// baz: string | null; +//// } +////} +////declare let foo: Foo; +/////*a*/foo && foo.bar ? foo.bar.baz : "whenFalse";/*b*/ + +// Do not offer refactor when true condition can be null. +goTo.select("a", "b"); +verify.not.refactorAvailable("Convert to optional chain expression") \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryExpression.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryExpression.ts new file mode 100644 index 0000000000000..ad68d59052080 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryExpression.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////a && a.b && /*a*//*b*/a.b.c; + +// verify that the refactor is offered for empty spans in expression statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a?.b?.c;`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryReturnStatement.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryReturnStatement.ts new file mode 100644 index 0000000000000..fe4f85484dfff --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanBinaryReturnStatement.ts @@ -0,0 +1,22 @@ +/// + +////let a = { b: { c: 0 } }; +////function f(){ +//// return a && a.b && /*a*//*b*/a.b.c; +////} + +// verify that the refactor is offered for empty spans in return statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +function f(){ + return a?.b?.c; +}`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanCallArgument.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanCallArgument.ts new file mode 100644 index 0000000000000..5b0a9cb22ed18 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanCallArgument.ts @@ -0,0 +1,16 @@ +/// + +////let foo = { bar: { baz: 0 } }; +////f(foo && foo.ba/*a*//*b*/r && foo.bar.baz); + +// allow for call arguments +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let foo = { bar: { baz: 0 } }; +f(foo?.bar?.baz);`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditional.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditional.ts new file mode 100644 index 0000000000000..caf1ccab89a12 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditional.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////a.b ? /*a*//*b*/a.b.c : "whenFalse"; + +// verify that the refactor is offered for empty spans in expression statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a.b?.c ?? "whenFalse";`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnKeyword.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnKeyword.ts new file mode 100644 index 0000000000000..3f7b6bf10fd53 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnKeyword.ts @@ -0,0 +1,22 @@ +/// + +////let a = { b: { c: 0 } }; +////function f(){ +//// ret/*a*//*b*/urn a.b ? a.b.c : "whenFalse"; +////} + +// verify that the refactor is offered for empty spans in return statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +function f(){ + return a.b?.c ?? "whenFalse"; +}`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnStatement.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnStatement.ts new file mode 100644 index 0000000000000..494cb91986d68 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanConditionalReturnStatement.ts @@ -0,0 +1,22 @@ +/// + +////let a = { b: { c: 0 } }; +////function f(){ +//// return a.b ? /*a*//*b*/a.b.c : "whenFalse"; +////} + +// verify that the refactor is offered for empty spans in return statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +function f(){ + return a.b?.c ?? "whenFalse"; +}`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVarKeyword.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVarKeyword.ts new file mode 100644 index 0000000000000..6f6bd981979ea --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVarKeyword.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////let/*a*//*b*/ x = a.b ? a.b.c : "whenFalse"; + +// verify that the refactor is offered for empty spans in variable statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let x = a.b?.c ?? "whenFalse";`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementBinary.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementBinary.ts new file mode 100644 index 0000000000000..b8233a55c4d89 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementBinary.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////let x = a && a.b && /*a*//*b*/a.b.c; + +// verify that the refactor is offered for empty spans in variable statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let x = a?.b?.c;`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementConditional.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementConditional.ts new file mode 100644 index 0000000000000..75445c055d59f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_EmptySpanVariableStatementConditional.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////let x = a.b ? /*a*//*b*/a.b.c : "whenFalse"; + +// verify that the refactor is offered for empty spans in variable statements. +goTo.select("a", "b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let x = a.b?.c ?? "whenFalse";`, + triggerReason: "invoked" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ExpressionStatementValidSpans.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ExpressionStatementValidSpans.ts new file mode 100644 index 0000000000000..67eab8346ed58 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ExpressionStatementValidSpans.ts @@ -0,0 +1,19 @@ +/// + +////let a = { b: { c: 0 } }; +/////*1a*/let x1 = a && a.b && a.b.c;/*1b*/ +////let x2 = /*2a*/a && a.b && a.b.c;/*2b*/ +////let x3 = /*3a*/a && a.b && a.b.c/*3b*/; +////let x4 = /*4a*/a.b ? a.b.c : "whenFalse"/*4b*/; + +goTo.select("1a", "1b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("2a", "2b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("3a", "3b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("4a", "4b"); +verify.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InFunctionCall.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InFunctionCall.ts new file mode 100644 index 0000000000000..964f0089d73ee --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InFunctionCall.ts @@ -0,0 +1,15 @@ +/// + +////let foo = { bar: { baz: 0 } }; +////f(/*a*/foo && foo.bar && foo.bar.baz/*b*/); + +// allow for call arguments +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let foo = { bar: { baz: 0 } }; +f(foo?.bar?.baz);` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InIfStatement.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InIfStatement.ts new file mode 100644 index 0000000000000..03562de6639c7 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_InIfStatement.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +////if(/*a*/a && a.b && a.b.c/*b*/){}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +if(a?.b?.c){};` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoInitialIdentifier.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoInitialIdentifier.ts new file mode 100644 index 0000000000000..29b7710dcd39f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoInitialIdentifier.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +/////*a*/a.b && a.b.c;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +a.b?.c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoPreviousCall.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoPreviousCall.ts new file mode 100644 index 0000000000000..24a072f572ceb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoPreviousCall.ts @@ -0,0 +1,15 @@ +/// + +////let a = { +//// b: () => { +//// return { +//// c: () => { +//// return { d: 0 }; +//// } +//// }; +//// } +////} +/////*a*/a && a.b() && a.b.c;/*b*/ + +goTo.select("a", "b"); +verify.not.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoRepeatCalls.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoRepeatCalls.ts new file mode 100644 index 0000000000000..99f34efe1bbd1 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NoRepeatCalls.ts @@ -0,0 +1,34 @@ +/// + +////let a = { b: ()=> { +//// return { +//// c: ()=> { +//// return { +//// d: 0 +//// } +//// } +//// } +////}}; +/////*1a*//*2a*/a && a.b && a.b().c/*1b*/ && a.b().c().d;/*2b*/ + +// We should stop at the first call for b since it may not be a pure function. +goTo.select("2a", "2b"); +verify.not.refactorAvailable("Convert to optional chain expression"); + +goTo.select("1a", "1b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: ()=> { + return { + c: ()=> { + return { + d: 0 + } + } + } +}}; +a?.b?.().c && a.b().c().d;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOptionalChain.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOptionalChain.ts new file mode 100644 index 0000000000000..a74717ebce8c8 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOptionalChain.ts @@ -0,0 +1,7 @@ +/// + +////let a = { b: { c: 0 } }; +/////*a*/a && a.b && a?.b?.c;/*b*/ + +goTo.select("a", "b"); +verify.not.refactorAvailable("Convert to optional chain expression"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOtherOperators.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOtherOperators.ts new file mode 100644 index 0000000000000..5dffd5cc7e108 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOtherOperators.ts @@ -0,0 +1,28 @@ +/// + +////let a = { b: { c: { d: 0 } } }; +/////*1a*/a || a.b && a.b.c && a.b.c.d;/*1b*/ +/////*2a*/a && a.b || a.b.c && a.b.c.d;/*2b*/ +/////*3a*/a && a.b && a.b.c || a.b.c.d;/*3b*/ +/////*4a*/a ?? a.b && a.b.c && a.b.c.d;/*4b*/ +/////*5a*/a && a.b ?? a.b.c || a.b.c.d;/*5b*/ +/////*6a*/a && a.b && a.b.c ?? a.b.c.d;/*6b*/ + +// Only offer refactor for && chains. +goTo.select("1a", "1b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +goTo.select("2a", "2b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +goTo.select("3a", "3b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +goTo.select("4a", "4b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +goTo.select("5a", "5b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); + +goTo.select("6a", "6b"); +verify.not.refactorAvailableForTriggerReason("implicit", "Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOutOfOrderSequence.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOutOfOrderSequence.ts new file mode 100644 index 0000000000000..4879612b27971 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_NotForOutOfOrderSequence.ts @@ -0,0 +1,9 @@ +/// + +////let a = { b: 0 }; +////let x = { b: 0 }; +/////*a*/a && x && a.b && x.y;/*b*/ + +// We don't currently offer a refactor for this case but should add it in the future. +goTo.select("a", "b"); +verify.not.refactorAvailable("Convert to optional chain expression"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_OptionalInterface.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_OptionalInterface.ts new file mode 100644 index 0000000000000..1d777daa8c04c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_OptionalInterface.ts @@ -0,0 +1,24 @@ +/// + +////interface Foo { +//// bar?:{ +//// baz?: string; +//// } +////} +////declare let foo: Foo | undefined; +/////*a*/foo && foo.bar && foo.bar.baz;/*b*/ + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`interface Foo { + bar?:{ + baz?: string; + } +} +declare let foo: Foo | undefined; +foo?.bar?.baz;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementBinary.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementBinary.ts new file mode 100644 index 0000000000000..78b39d484fdfd --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementBinary.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////function f(){ +//// return /*a*/a && a.b && a.b.c/*b*/; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +function f(){ + return a?.b?.c; +}` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementConditional.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementConditional.ts new file mode 100644 index 0000000000000..3849741eb9e97 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementConditional.ts @@ -0,0 +1,18 @@ +/// + +////let a = { b: { c: 0 } }; +////function f(){ +//// return /*a*/a.b ? a.b.c : "whenFalse"/*b*/; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +function f(){ + return a.b?.c ?? "whenFalse"; +}` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementValidSpans.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementValidSpans.ts new file mode 100644 index 0000000000000..54a4c0d90a287 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_ReturnStatementValidSpans.ts @@ -0,0 +1,28 @@ +/// + +////let a = { b: { c: 0 } }; +////function f()1{ +//// /*1a*/return a && a.b && a.b.c;/*1b*/ +////} +////function f()2{ +//// return /*2a*/a && a.b && a.b.c;/*2b*/ +////} +////function f()3{ +//// return /*3a*/a && a.b && a.b.c/*3b*/; +////} +////function f()4{ +//// return /*4a*/a.b ? a.b.c : "whenFalse";/*4b*/ +////} + +// valid spans for return statement +goTo.select("1a", "1b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("2a", "2b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("3a", "3b"); +verify.refactorAvailable("Convert to optional chain expression"); + +goTo.select("4a", "4b"); +verify.refactorAvailable("Convert to optional chain expression"); diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SemicolonNotSelected.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SemicolonNotSelected.ts new file mode 100644 index 0000000000000..205c3f893347e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SemicolonNotSelected.ts @@ -0,0 +1,14 @@ +/// + +////let a = { b: { c: 0 } }; +////let x = /*a*/a && a.b && a.b.c/*b*/; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let x = a?.b?.c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SparseAccess.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SparseAccess.ts new file mode 100644 index 0000000000000..13c0fac40cd3a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SparseAccess.ts @@ -0,0 +1,15 @@ +/// + +////let a = { b: { c: { d: { e: {f: 0} } } } }; +/////*a*/a.b && a.b.c.d && a.b.c.d.e.f;/*b*/ + +// Only convert the accesses for which existence is checked. +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: { d: { e: {f: 0} } } } }; +a.b?.c.d?.e.f;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithPrefix1.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithPrefix1.ts new file mode 100644 index 0000000000000..ed6061a8e6726 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithPrefix1.ts @@ -0,0 +1,19 @@ +/// + +////let a = { b: { c: 0 } }; +////let foo; +////let bar; +////foo && bar && /*a*/a && a.b && a.b.c;/*b*/ + +// verify that we stop at an invalid prefix sequence. +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let foo; +let bar; +foo && bar && a?.b?.c;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix1.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix1.ts new file mode 100644 index 0000000000000..ab48eb8c85dec --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix1.ts @@ -0,0 +1,19 @@ +/// + +////let a = { b: { c: 0 } }; +////let foo; +////let bar; +/////*a*/a && a.b && a.b.c/*b*/ && foo && bar; + +// verify that we stop at an invalid suffix sequence. +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: { c: 0 } }; +let foo; +let bar; +a?.b?.c && foo && bar;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix2.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix2.ts new file mode 100644 index 0000000000000..ec038ae76c67f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionWithSuffix2.ts @@ -0,0 +1,17 @@ +/// + +////let a = { b: 0 }; +////let x = { y: 0 }; +/////*a*/a && a.b()/*b*/ && x && x.y(); + +// verify that we stop at a suffix sequence which is otherwise valid. +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: 0 }; +let x = { y: 0 }; +a?.b() && x && x.y();` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionsWithPrefix2.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionsWithPrefix2.ts new file mode 100644 index 0000000000000..15b3dbb8e70dc --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_SubexpressionsWithPrefix2.ts @@ -0,0 +1,17 @@ +/// + +////let a = { b: 0 }; +////let x = { y: 0 }; +////a && a.b && /*a*/x && x.y;/*b*/ + +// Verify that we stop at a prefix sequence that is otherwise valid. +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to optional chain expression", + actionName: "Convert to optional chain expression", + actionDescription: "Convert to optional chain expression", + newContent: +`let a = { b: 0 }; +let x = { y: 0 }; +a && a.b && x?.y;` +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToOptionalChainExpression_UnknownSymbol.ts b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_UnknownSymbol.ts new file mode 100644 index 0000000000000..ea4b6d6c1683b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToOptionalChainExpression_UnknownSymbol.ts @@ -0,0 +1,6 @@ +/// + +/////*a*/foo && foo.bar;/*b*/ + +goTo.select("a", "b"); +verify.refactorAvailable("Convert to optional chain expression") \ No newline at end of file diff --git a/tests/cases/fourslash/referencesForStatementKeywords.ts b/tests/cases/fourslash/referencesForStatementKeywords.ts index e5a171f0d9f10..f089e9d100013 100644 --- a/tests/cases/fourslash/referencesForStatementKeywords.ts +++ b/tests/cases/fourslash/referencesForStatementKeywords.ts @@ -17,7 +17,7 @@ //// ////// export ... from ... ////[|{| "id": "exportDecl1" |}[|export|] [|type|] * [|from|] "[|{| "isWriteAccess": false, "isDefinition": false, "contextRangeId": "exportDecl1" |}./g|]";|] -////[|{| "id": "exportDecl2" |}[|export|] [|type|] [|{| "id": "exportDecl2_namespaceExport" |}* [|as|] [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "exportDecl2_namespaceExport" |}H|]|] [|from|] "[|{| "isWriteAccess": false, "isDefinition": false, "contextRangeId": "exportDecl2" |}./h|]";|] +////[|{| "id": "exportDecl2" |}[|export|] [|type|] [|{| "id": "exportDecl2_namespaceExport" |}* [|as|] [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "exportDecl2" |}H|]|] [|from|] "[|{| "isWriteAccess": false, "isDefinition": false, "contextRangeId": "exportDecl2" |}./h|]";|] ////[|{| "id": "exportDecl3" |}[|export|] [|type|] { [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "exportDecl3" |}I|] } [|from|] "[|{| "isWriteAccess": false, "isDefinition": false, "contextRangeId": "exportDecl3" |}./i|]";|] ////[|{| "id": "exportDecl4" |}[|export|] [|type|] { j1, j2 [|as|] [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "exportDecl4" |}j3|] } [|from|] "[|{| "isWriteAccess": false, "isDefinition": false, "contextRangeId": "exportDecl4" |}./j|]";|] ////[|{| "id": "typeDecl1" |}type [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeId": "typeDecl1" |}Z1|] = 1;|] diff --git a/tests/cases/fourslash/renameRestBindingElement.ts b/tests/cases/fourslash/renameRestBindingElement.ts new file mode 100644 index 0000000000000..59e58c37f4a27 --- /dev/null +++ b/tests/cases/fourslash/renameRestBindingElement.ts @@ -0,0 +1,13 @@ +/// + +////interface I { +//// a: number; +//// b: number; +//// c: number; +////} +////function foo([|{ a, ...[|{| "contextRangeIndex": 0 |}rest|] }: I|]) { +//// [|rest|]; +////} + +const [r0Def, r0, r1] = test.ranges(); +verify.renameLocations(r0, { ranges: [r0, r1], providePrefixAndSuffixTextForRename: true }); diff --git a/tests/cases/fourslash/server/convertFunctionToEs6Class-server1.ts b/tests/cases/fourslash/server/convertFunctionToEs6Class-server1.ts index 316572063a5ea..7e34b109f5ccc 100644 --- a/tests/cases/fourslash/server/convertFunctionToEs6Class-server1.ts +++ b/tests/cases/fourslash/server/convertFunctionToEs6Class-server1.ts @@ -22,6 +22,6 @@ class fn {\r bar() {\r console.log('hello world');\r }\r -}\r +} `, }); diff --git a/tests/cases/fourslash/server/convertFunctionToEs6Class-server2.ts b/tests/cases/fourslash/server/convertFunctionToEs6Class-server2.ts index 2f9c1a88bdf7c..470325c5ae7c7 100644 --- a/tests/cases/fourslash/server/convertFunctionToEs6Class-server2.ts +++ b/tests/cases/fourslash/server/convertFunctionToEs6Class-server2.ts @@ -16,9 +16,9 @@ verify.codeFix({ description: "Convert function to an ES2015 class", newFileContent: -`/**\r - * JSDoc Comment\r - */\r +`/** + * JSDoc Comment + */ class fn {\r constructor() {\r this.baz = 10;\r @@ -26,6 +26,6 @@ class fn {\r bar() {\r console.log('hello world');\r }\r -}\r +} `, }); diff --git a/tests/cases/fourslash/signatureHelpExpandedRestUnlabeledTuples.ts b/tests/cases/fourslash/signatureHelpExpandedRestUnlabeledTuples.ts new file mode 100644 index 0000000000000..6ddd19f072829 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpExpandedRestUnlabeledTuples.ts @@ -0,0 +1,36 @@ +/// + +////export function complex(item: string, another: string, ...rest: [] | [object, (err: Error) => void] | [(err: Error) => void, ...object[]]) { +//// +////} +//// +////complex(/*1*/); +////complex("ok", "ok", /*2*/); +////complex("ok", "ok", e => void e, {}, /*3*/); + +verify.signatureHelp( + { + marker: "1", + text: "complex(item: string, another: string): void", + overloadsCount: 3, + parameterCount: 2, + parameterName: "item", + parameterSpan: "item: string", + isVariadic: false, + }, + { + marker: "2", + text: "complex(item: string, another: string, rest_0: object, rest_1: (err: Error) => void): void", + overloadsCount: 3, + parameterCount: 4, + parameterName: "rest_0", + parameterSpan: "rest_0: object", + isVariadic: false, + }, + { + marker: "3", + text: "complex(item: string, another: string, rest_0: (err: Error) => void, ...rest_1: object[]): void", + overloadsCount: 3, + isVariadic: true, + }, +); diff --git a/tests/cases/fourslash/signatureHelpExpandedTuplesArgumentIndex.ts b/tests/cases/fourslash/signatureHelpExpandedTuplesArgumentIndex.ts new file mode 100644 index 0000000000000..5c97b874c63a4 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpExpandedTuplesArgumentIndex.ts @@ -0,0 +1,94 @@ +/// + +////function foo(...args: [string, string] | [number, string, string] +////) { +//// +////} +//// +////foo(123/*1*/,) +////foo(""/*2*/, ""/*3*/) +////foo(123/*4*/, ""/*5*/, ) +////foo(123/*6*/, ""/*7*/, ""/*8*/) + +verify.signatureHelp( + { + marker: "1", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_0", + parameterSpan: "args_0: number", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, + { + marker: "2", + text: "foo(args_0: string, args_1: string): void", + overloadsCount: 2, + parameterCount: 2, + parameterName: "args_0", + parameterSpan: "args_0: string", + isVariadic: false, + overrideSelectedItemIndex: 0 + }, + { + marker: "3", + text: "foo(args_0: string, args_1: string): void", + overloadsCount: 2, + parameterCount: 2, + parameterName: "args_1", + parameterSpan: "args_1: string", + isVariadic: false, + overrideSelectedItemIndex: 0 + }, + { + marker: "4", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_0", + parameterSpan: "args_0: number", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, + { + marker: "5", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_1", + parameterSpan: "args_1: string", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, + { + marker: "6", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_0", + parameterSpan: "args_0: number", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, + { + marker: "7", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_1", + parameterSpan: "args_1: string", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, + { + marker: "8", + text: "foo(args_0: number, args_1: string, args_2: string): void", + overloadsCount: 2, + parameterCount: 3, + parameterName: "args_2", + parameterSpan: "args_2: string", + isVariadic: false, + overrideSelectedItemIndex: 1 + }, +); diff --git a/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts b/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts new file mode 100644 index 0000000000000..73b22459d6303 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpJSMissingIdentifier.ts @@ -0,0 +1,9 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: test.js +////log(/**/) + +verify.noSignatureHelp(""); diff --git a/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts b/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts new file mode 100644 index 0000000000000..1c1cf427528b0 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpJSMissingPropertyAccess.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: test.js +////foo.filter(/**/) + +goTo.marker(""); +verify.signatureHelp({ + text: "ReadonlyArray.filter(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[]", + overloadsCount: 2, + docComment: "Returns the elements of an array that meet the condition specified in a callback function.", + parameterDocComment: "A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.", + tags: [ + { name: "param", text: "predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array." }, + { name: "param", text: "thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value." } + ] +}); diff --git a/tests/cases/fourslash/toggleLineComment1.ts b/tests/cases/fourslash/toggleLineComment1.ts new file mode 100644 index 0000000000000..1f72de7b40276 --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment1.ts @@ -0,0 +1,18 @@ +// Simple comment and uncomment. + +//// let var1[| = 1; +//// let var2 = 2; +//// let var3 |]= 3; +//// +//// //let var4[| = 1; +//// //let var5 = 2; +//// //let var6 |]= 3; + +verify.toggleLineComment( + `//let var1 = 1; +//let var2 = 2; +//let var3 = 3; + +let var4 = 1; +let var5 = 2; +let var6 = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment10.ts b/tests/cases/fourslash/toggleLineComment10.ts new file mode 100644 index 0000000000000..0f6c3d271988b --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment10.ts @@ -0,0 +1,11 @@ +// Close and open multiline comments if the line already contains more comments. + +//@Filename: file.tsx +//// const a =
+//// Som[||]e{/* T */}ext +////
; + +verify.toggleLineComment( + `const a =
+ {/*Some*/}{/* T */}{/*ext*/} +
;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment2.ts b/tests/cases/fourslash/toggleLineComment2.ts new file mode 100644 index 0000000000000..710bd5ef3f7db --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment2.ts @@ -0,0 +1,20 @@ +// When indentation is different between lines it should get the left most indentation +// and use that for all lines. +// When uncommeting, doesn't matter what indentation the line has. + +//// let var1[| = 1; +//// let var2 = 2; +//// let var3 |]= 3; +//// +//// // let var4[| = 1; +//// //let var5 = 2; +//// // let var6 |]= 3; + +verify.toggleLineComment( + ` // let var1 = 1; + //let var2 = 2; + // let var3 = 3; + + let var4 = 1; +let var5 = 2; + let var6 = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment3.ts b/tests/cases/fourslash/toggleLineComment3.ts new file mode 100644 index 0000000000000..d8f9aeabb99db --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment3.ts @@ -0,0 +1,26 @@ +// Comment and uncomment ignores empty lines. + +//// let var1[| = 1; +//// +//// let var2 = 2; +//// +//// let var3 |]= 3; +//// +//// //let var4[| = 1; +//// +//// //let var5 = 2; +//// +//// //let var6 |]= 3; + +verify.toggleLineComment( + `//let var1 = 1; + +//let var2 = 2; + +//let var3 = 3; + +let var4 = 1; + +let var5 = 2; + +let var6 = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment4.ts b/tests/cases/fourslash/toggleLineComment4.ts new file mode 100644 index 0000000000000..5e4beb6070a7e --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment4.ts @@ -0,0 +1,18 @@ +// If at least one line is not commented then comment all lines again. + +//// //const a[| = 1; +//// const b = 2 +//// //const c =|] 3; +//// +//// ////const d[| = 4; +//// //const e = 5; +//// ////const e =|] 6; + +verify.toggleLineComment( + `// //const a = 1; +//const b = 2 +// //const c = 3; + +//const d = 4; +const e = 5; +//const e = 6;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment5.ts b/tests/cases/fourslash/toggleLineComment5.ts new file mode 100644 index 0000000000000..bec00a9233323 --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment5.ts @@ -0,0 +1,22 @@ +// Comments inside strings are still considered comments. + +//// let var1 = ` +//// //some stri[|ng +//// //some other|] string +//// `; +//// +//// let var2 = ` +//// some stri[|ng +//// some other|] string +//// `; + +verify.toggleLineComment( + `let var1 = \` +some string +some other string +\`; + +let var2 = \` +//some string +//some other string +\`;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment6.ts b/tests/cases/fourslash/toggleLineComment6.ts new file mode 100644 index 0000000000000..4274cc18308ce --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment6.ts @@ -0,0 +1,15 @@ +// Selection is at the start of jsx its still js. + +//@Filename: file.tsx +//// let a = ( +//// [|
+//// some text|] +////
+//// ); + +verify.toggleLineComment( + `let a = ( + //
+ // some text +
+);`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment7.ts b/tests/cases/fourslash/toggleLineComment7.ts new file mode 100644 index 0000000000000..5a6cbb002fbf5 --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment7.ts @@ -0,0 +1,29 @@ +// Common comment line cases. + +//@Filename: file.tsx +//// const a = +//// [| +//// |] +//// ; +//// const b = +//// {/**/} +//// {/**/} +//// ; +//// const c = [| +//// +//// +//// ; + +verify.toggleLineComment( + `const a = + {/**/} + {/**/} +; +const b = + + +; +//const c = +// +// +;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment8.ts b/tests/cases/fourslash/toggleLineComment8.ts new file mode 100644 index 0000000000000..1c3bed3fd8eb1 --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment8.ts @@ -0,0 +1,30 @@ +// When indentation is different between lines it should get the left most indentation +// and use that for all lines. +// When uncommeting, doesn't matter what indentation the line has. + +//@Filename: file.tsx +//// const a =
+//// [|
+//// SomeText +////
|] +////
; +//// +//// const b =
+//// {/*[|
*/} +//// {/* SomeText*/} +//// {/*
|]*/} +////
; + + +verify.toggleLineComment( + `const a =
+ {/*
*/} + {/* SomeText*/} + {/*
*/} +
; + +const b =
+
+ SomeText +
+
;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleLineComment9.ts b/tests/cases/fourslash/toggleLineComment9.ts new file mode 100644 index 0000000000000..1fbaea7ea383a --- /dev/null +++ b/tests/cases/fourslash/toggleLineComment9.ts @@ -0,0 +1,18 @@ +// If at least one line is not commented then comment all lines again. +// TODO: Not sure about this one. The default behavior for line comment is to add en extra +// layer of comments (see toggleLineComment4 test). For jsx this doesn't work right as it's actually +// multiline comment. Figure out what to do. + +//@Filename: file.tsx +//// const a =
+//// {/*[|
*/} +//// SomeText +//// {/*
|]*/} +////
; + +verify.toggleLineComment( + `const a =
+ {/*
*/} + {/* SomeText*/} + {/*
*/} +
;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment1.ts b/tests/cases/fourslash/toggleMultilineComment1.ts new file mode 100644 index 0000000000000..f76e9d564734f --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment1.ts @@ -0,0 +1,30 @@ +// Simple multiline comment and uncomment. + +//// let var1[| = 1; +//// let var2 = 2; +//// let var3 |]= 3; +//// +//// let var4/* = 1; +//// let var5 [||]= 2; +//// let var6 */= 3; +//// +//// [|/*let var7 = 1; +//// let var8 = 2; +//// let var9 = 3;*/|] +//// +//// let var10[||] = 10; + +verify.toggleMultilineComment( + `let var1/* = 1; +let var2 = 2; +let var3 */= 3; + +let var4 = 1; +let var5 = 2; +let var6 = 3; + +let var7 = 1; +let var8 = 2; +let var9 = 3; + +let var10/**/ = 10;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment2.ts b/tests/cases/fourslash/toggleMultilineComment2.ts new file mode 100644 index 0000000000000..a3a8cf70f786d --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment2.ts @@ -0,0 +1,35 @@ +// If selection is outside of a multiline comment then insert comment +// instead of removing. + +//// let var1/* = 1; +//// let var2 [|= 2; +//// let var3 */= 3;|] +//// +//// [|let var4/* = 1; +//// let var5 |]= 2; +//// let var6 */= 3; +//// +//// [|let var7/* = 1; +//// let var8 = 2; +//// let var9 */= 3;|] +//// +//// /*let va[|r10 = 1;*/ +//// let var11 = 2; +//// /*let var12|] = 3;*/ + +verify.toggleMultilineComment( + `let var1/* = 1; +let var2 *//*= 2; +let var3 *//*= 3;*/ + +/*let var4*//* = 1; +let var5 *//*= 2; +let var6 */= 3; + +/*let var7*//* = 1; +let var8 = 2; +let var9 *//*= 3;*/ + +/*let va*//*r10 = 1;*//* +let var11 = 2; +*//*let var12*//* = 3;*/`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment3.ts b/tests/cases/fourslash/toggleMultilineComment3.ts new file mode 100644 index 0000000000000..bcfa3418d971a --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment3.ts @@ -0,0 +1,28 @@ +/// + +// If range is inside a single line comment, just add the multiline comment. + +//// // let va[|r1 = 1; +//// let var2 = 2; +//// // let var3|] = 3; +//// +//// // let va[|r4 = 1; +//// let var5 = 2; +//// /* let var6|] = 3;*/ +//// +//// /* let va[|r7 = 1;*/ +//// let var8 = 2; +//// // let var9|] = 3; + +verify.toggleMultilineComment( + `/*// let var1 = 1; +let var2 = 2; +// let var3*/ = 3; + +/*// let var4 = 1; +let var5 = 2; +*//* let var6*//* = 3;*/ + +/* let va*//*r7 = 1;*//* +let var8 = 2; +// let var9*/ = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment4.ts b/tests/cases/fourslash/toggleMultilineComment4.ts new file mode 100644 index 0000000000000..216a308ae44d5 --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment4.ts @@ -0,0 +1,7 @@ +// This is an edgecase. The string contains a multiline comment syntax but it is a string +// and not actually a comment. When toggling it doesn't get escaped or appended comments. +// The result would be a portion of the selection to be "not commented". + +//// /*let s[|omeLongVa*/riable = "Some other /*long th*/in|]g"; + +verify.toggleMultilineComment(`/*let s*//*omeLongVa*//*riable = "Some other /*long th*/in*/g";`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment5.ts b/tests/cases/fourslash/toggleMultilineComment5.ts new file mode 100644 index 0000000000000..0dea4ebbff44e --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment5.ts @@ -0,0 +1,34 @@ +// Jsx uses block comments for each line commented. + +// Common JSX comment scenarios + +//@Filename: file.tsx +//// const a =
[|
;|] +//// const b =
This is [|valid HTML &|] JSX at the same time.
; +//// const c = +//// [| +//// |] +//// ; +//// const d = +//// +//// |] +//// ; +//// const e = [|{'foo'}|]; +//// const f =
Some text;|] +//// const g =
Some text<[|/div>;|] + +verify.toggleMultilineComment( + `const a =
{/*
;*/} +const b =
This is {/*valid HTML &*/} JSX at the same time.
; +const c = + {/* + */} +; +const d = + + */} +; +const e = {/*{'foo'}*/}; +const f =
Some text;*/} +const g =
Some text<{/*/div>;*/}` +); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment6.ts b/tests/cases/fourslash/toggleMultilineComment6.ts new file mode 100644 index 0000000000000..caa60504fd17c --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment6.ts @@ -0,0 +1,43 @@ +// Jsx uses multiline comments for each line commented. + +// Selection is outside of a multiline comments inserts multiline comments instead of removing. +// There's some variations between jsx and js comments depending on the position. + +//@Filename: file.tsx +//// const var1 =
Tex{/*t1
; +//// const var2 =
Text2[|
; +//// const var3 =
Tex*/}t3
;|] +//// +//// [|const var4 =
Tex{/*t4
; +//// const var5 = Text5
; +//// const var6 =
Tex*/}t6
; +//// +//// [|const var7 =
Tex{/*t7
; +//// const var8 =
Text8
; +//// const var9 =
Tex*/}t9
;|] +//// +//// const var10 =
+//// {/*
T[|ext
*/} +////
Text
+//// {/*
Text|]
*/} +////
; + +verify.toggleMultilineComment( + `const var1 =
Tex{/*t1
; +const var2 =
Text2*/}{/*
; +const var3 =
Tex*/}{/*t3
;*/} + +/*const var4 =
Tex{*//*t4
; +const var5 = Text5
; +const var6 =
Tex*/}t6
; + +/*const var7 =
Tex{*//*t7
; +const var8 =
Text8
; +const var9 =
Tex*//*}t9
;*/ + +const var10 =
+ {/*
T*/}{/*ext
*/}{/* +
Text
+ */}{/*
Text*/}{/*
*/} +
;` +); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment7.ts b/tests/cases/fourslash/toggleMultilineComment7.ts new file mode 100644 index 0000000000000..d4c711aee68bb --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment7.ts @@ -0,0 +1,33 @@ +// Cases where the cursor is inside JSX like sintax but it's actually js. + +//@Filename: file.tsx +//// const a = ( +//// [|
+//// some text|] +////
+//// ); +//// const b = ; +//// const c = ; +//// const d = ; +//// const e = ;|] +//// const f = [ +//// [|
  • First item
  • , +////
  • Second item
  • ,|] +////
  • Third item
  • , +//// ]; + +verify.toggleMultilineComment( + `const a = ( + /*
    + some text*/ +
    +); +const b = ; +const c = ; +const d = ; +const e = ;*/ +const f = [ + /*
  • First item
  • , +
  • Second item
  • ,*/ +
  • Third item
  • , +];`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment8.ts b/tests/cases/fourslash/toggleMultilineComment8.ts new file mode 100644 index 0000000000000..724c597dd0639 --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment8.ts @@ -0,0 +1,12 @@ +// If the range only contains comments, uncomment all. + +//// /*let var[|1 = 1;*/ +//// /*let var2 = 2;*/ +//// +//// /*let var3 |]= 3;*/ + +verify.toggleMultilineComment( + `let var1 = 1; +let var2 = 2; + +let var3 = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/toggleMultilineComment9.ts b/tests/cases/fourslash/toggleMultilineComment9.ts new file mode 100644 index 0000000000000..f9761a98773d5 --- /dev/null +++ b/tests/cases/fourslash/toggleMultilineComment9.ts @@ -0,0 +1,30 @@ +// When there's is only whitespace, insert comment. If there is whitespace but theres a comment in bewteen, then uncomment. + +//// /*let var1[| = 1;*/ +//// |] +//// +//// [| +//// /*let var2 = 2;*/|] +//// +//// [| +//// +//// |] +//// +//// [||] +//// +//// let var3[||] = 3; + +verify.toggleMultilineComment( + `let var1 = 1; + + + +let var2 = 2; + +/* + +*/ + + /**/ + +let var3/**/ = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/uncommentSelection1.ts b/tests/cases/fourslash/uncommentSelection1.ts new file mode 100644 index 0000000000000..2245cbc2d007a --- /dev/null +++ b/tests/cases/fourslash/uncommentSelection1.ts @@ -0,0 +1,42 @@ +// Simple comment selection cases. + +//// //let var1[| = 1; +//// //let var2 = 2; +//// //let var3 |]= 3; +//// +//// //let var4[| = 4; +//// /*let var5 = 5;*/ +//// //let var6 = 6; +//// +//// let var7 |]= 7; +//// +//// let var8/* = 1; +//// let var9 [||]= 2; +//// let var10 */= 3; +//// +//// let var11[||]/* = 1; +//// let var12 = 2; +//// let var13 */= 3; +//// +//// ////let var14 [||]= 14; + +verify.uncommentSelection( + `let var1 = 1; +let var2 = 2; +let var3 = 3; + +let var4 = 4; +let var5 = 5; +let var6 = 6; + +let var7 = 7; + +let var8 = 1; +let var9 = 2; +let var10 = 3; + +let var11 = 1; +let var12 = 2; +let var13 = 3; + +//let var14 = 14;`); \ No newline at end of file diff --git a/tests/cases/fourslash/uncommentSelection2.ts b/tests/cases/fourslash/uncommentSelection2.ts new file mode 100644 index 0000000000000..745000d9c4d28 --- /dev/null +++ b/tests/cases/fourslash/uncommentSelection2.ts @@ -0,0 +1,34 @@ +// Common uncomment jsx cases + +//@Filename: file.tsx +//// const a = +//// {/**/} +//// {/**/} +//// ; +//// +//// const b =
    +//// {/*[|
    */} +//// SomeText +//// {/*
    |]*/} +////
    ; +//// +//// const c = +//// [||]{/**/} +//// ; + + +verify.uncommentSelection( + `const a = + + +; + +const b =
    +
    + SomeText +
    +
    ; + +const c = + +;`); \ No newline at end of file diff --git a/tests/cases/fourslash/uncommentSelection3.ts b/tests/cases/fourslash/uncommentSelection3.ts new file mode 100644 index 0000000000000..9ad68476ceb64 --- /dev/null +++ b/tests/cases/fourslash/uncommentSelection3.ts @@ -0,0 +1,34 @@ +// Remove all comments within the selection + +//// let var1/* = 1; +//// let var2 [|= 2; +//// let var3 */= 3;|] +//// +//// [|let var4/* = 1; +//// let var5 |]= 2; +//// let var6 */= 3; +//// +//// [|let var7/* = 1; +//// let var8 = 2; +//// let var9 */= 3;|] +//// +//// /*let va[|r10 = 1;*/ +//// let var11 = 2; +//// /*let var12|] = 3;*/ + +verify.uncommentSelection( + `let var1 = 1; +let var2 = 2; +let var3 = 3; + +let var4 = 1; +let var5 = 2; +let var6 = 3; + +let var7 = 1; +let var8 = 2; +let var9 = 3; + +let var10 = 1; +let var11 = 2; +let var12 = 3;`); \ No newline at end of file diff --git a/tests/cases/fourslash/uncommentSelection4.ts b/tests/cases/fourslash/uncommentSelection4.ts new file mode 100644 index 0000000000000..63faedaeddb20 --- /dev/null +++ b/tests/cases/fourslash/uncommentSelection4.ts @@ -0,0 +1,40 @@ +// Remove all comments in jsx. + +//@Filename: file.tsx +//// const var1 =
    Tex{/*t1
    ; +//// const var2 =
    Text2[|
    ; +//// const var3 =
    Tex*/}t3
    ;|] +//// +//// [|const var4 =
    Tex{/*t4
    ; +//// const var5 = Text5
    ; +//// const var6 =
    Tex*/}t6
    ; +//// +//// [|const var7 =
    Tex{/*t7
    ; +//// const var8 =
    Text8
    ; +//// const var9 =
    Tex*/}t9
    ;|] +//// +//// const var10 =
    +//// {/*
    T[|ext
    */} +////
    Text
    +//// {/*
    Text|]
    */} +////
    ; + +verify.uncommentSelection( + `const var1 =
    Text1
    ; +const var2 =
    Text2
    ; +const var3 =
    Text3
    ; + +const var4 =
    Text4
    ; +const var5 =
    Text5
    ; +const var6 =
    Text6
    ; + +const var7 =
    Text7
    ; +const var8 =
    Text8
    ; +const var9 =
    Text9
    ; + +const var10 =
    +
    Text
    +
    Text
    +
    Text
    +
    ;` +); \ No newline at end of file