tsc-ts 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -2
- package/dist/api/compiler/ast-utilities.d.ts +82 -0
- package/dist/api/compiler/ast-utilities.js +462 -0
- package/dist/api/compiler/ast.d.ts +2351 -0
- package/dist/api/compiler/ast.js +11212 -0
- package/dist/api/compiler/astnav.d.ts +37 -0
- package/dist/api/compiler/astnav.js +767 -0
- package/dist/api/compiler/binder-utilities.d.ts +182 -0
- package/dist/api/compiler/binder-utilities.js +1241 -0
- package/dist/api/compiler/binder.d.ts +33 -0
- package/dist/api/compiler/binder.js +2359 -0
- package/dist/api/compiler/character-codes.d.ts +161 -0
- package/dist/api/compiler/character-codes.js +160 -0
- package/dist/api/compiler/checker-calls.d.ts +46 -0
- package/dist/api/compiler/checker-calls.js +1641 -0
- package/dist/api/compiler/checker-classes.d.ts +30 -0
- package/dist/api/compiler/checker-classes.js +582 -0
- package/dist/api/compiler/checker-contextual.d.ts +77 -0
- package/dist/api/compiler/checker-contextual.js +1136 -0
- package/dist/api/compiler/checker-declaration-order.d.ts +12 -0
- package/dist/api/compiler/checker-declaration-order.js +357 -0
- package/dist/api/compiler/checker-declarations.d.ts +33 -0
- package/dist/api/compiler/checker-declarations.js +888 -0
- package/dist/api/compiler/checker-declared-types.d.ts +48 -0
- package/dist/api/compiler/checker-declared-types.js +788 -0
- package/dist/api/compiler/checker-decorators.d.ts +26 -0
- package/dist/api/compiler/checker-decorators.js +562 -0
- package/dist/api/compiler/checker-deprecation.d.ts +33 -0
- package/dist/api/compiler/checker-deprecation.js +314 -0
- package/dist/api/compiler/checker-destructuring.d.ts +34 -0
- package/dist/api/compiler/checker-destructuring.js +584 -0
- package/dist/api/compiler/checker-elaboration.d.ts +15 -0
- package/dist/api/compiler/checker-elaboration.js +291 -0
- package/dist/api/compiler/checker-emit-helpers.d.ts +58 -0
- package/dist/api/compiler/checker-emit-helpers.js +154 -0
- package/dist/api/compiler/checker-emit-resolver.d.ts +75 -0
- package/dist/api/compiler/checker-emit-resolver.js +580 -0
- package/dist/api/compiler/checker-evaluator.d.ts +27 -0
- package/dist/api/compiler/checker-evaluator.js +188 -0
- package/dist/api/compiler/checker-expressions.d.ts +67 -0
- package/dist/api/compiler/checker-expressions.js +1351 -0
- package/dist/api/compiler/checker-features.d.ts +6 -0
- package/dist/api/compiler/checker-features.js +354 -0
- package/dist/api/compiler/checker-flow.d.ts +86 -0
- package/dist/api/compiler/checker-flow.js +169 -0
- package/dist/api/compiler/checker-functions.d.ts +43 -0
- package/dist/api/compiler/checker-functions.js +1002 -0
- package/dist/api/compiler/checker-generated-code.d.ts +25 -0
- package/dist/api/compiler/checker-generated-code.js +168 -0
- package/dist/api/compiler/checker-globals.d.ts +14 -0
- package/dist/api/compiler/checker-globals.js +37 -0
- package/dist/api/compiler/checker-grammar.d.ts +35 -0
- package/dist/api/compiler/checker-grammar.js +2587 -0
- package/dist/api/compiler/checker-heritage.d.ts +28 -0
- package/dist/api/compiler/checker-heritage.js +901 -0
- package/dist/api/compiler/checker-inference.d.ts +179 -0
- package/dist/api/compiler/checker-inference.js +2105 -0
- package/dist/api/compiler/checker-iteration.d.ts +115 -0
- package/dist/api/compiler/checker-iteration.js +857 -0
- package/dist/api/compiler/checker-javascript.d.ts +42 -0
- package/dist/api/compiler/checker-javascript.js +442 -0
- package/dist/api/compiler/checker-jsdoc.d.ts +30 -0
- package/dist/api/compiler/checker-jsdoc.js +320 -0
- package/dist/api/compiler/checker-jsx.d.ts +94 -0
- package/dist/api/compiler/checker-jsx.js +1433 -0
- package/dist/api/compiler/checker-literals.d.ts +6 -0
- package/dist/api/compiler/checker-literals.js +43 -0
- package/dist/api/compiler/checker-members.d.ts +200 -0
- package/dist/api/compiler/checker-members.js +2148 -0
- package/dist/api/compiler/checker-modules.d.ts +85 -0
- package/dist/api/compiler/checker-modules.js +2141 -0
- package/dist/api/compiler/checker-narrowing.d.ts +120 -0
- package/dist/api/compiler/checker-narrowing.js +2797 -0
- package/dist/api/compiler/checker-object-literals.d.ts +14 -0
- package/dist/api/compiler/checker-object-literals.js +483 -0
- package/dist/api/compiler/checker-operators.d.ts +33 -0
- package/dist/api/compiler/checker-operators.js +1040 -0
- package/dist/api/compiler/checker-overloads.d.ts +7 -0
- package/dist/api/compiler/checker-overloads.js +271 -0
- package/dist/api/compiler/checker-property-access.d.ts +34 -0
- package/dist/api/compiler/checker-property-access.js +672 -0
- package/dist/api/compiler/checker-services.d.ts +49 -0
- package/dist/api/compiler/checker-services.js +995 -0
- package/dist/api/compiler/checker-signatures.d.ts +55 -0
- package/dist/api/compiler/checker-signatures.js +789 -0
- package/dist/api/compiler/checker-source-file.d.ts +27 -0
- package/dist/api/compiler/checker-source-file.js +619 -0
- package/dist/api/compiler/checker-statements.d.ts +18 -0
- package/dist/api/compiler/checker-statements.js +226 -0
- package/dist/api/compiler/checker-super.d.ts +13 -0
- package/dist/api/compiler/checker-super.js +241 -0
- package/dist/api/compiler/checker-symbol-types.d.ts +51 -0
- package/dist/api/compiler/checker-symbol-types.js +955 -0
- package/dist/api/compiler/checker-symbols.d.ts +181 -0
- package/dist/api/compiler/checker-symbols.js +1784 -0
- package/dist/api/compiler/checker-type-factory.d.ts +142 -0
- package/dist/api/compiler/checker-type-factory.js +2542 -0
- package/dist/api/compiler/checker-type-nodes.d.ts +26 -0
- package/dist/api/compiler/checker-type-nodes.js +828 -0
- package/dist/api/compiler/checker-type-operators.d.ts +109 -0
- package/dist/api/compiler/checker-type-operators.js +1842 -0
- package/dist/api/compiler/checker-types.d.ts +1093 -0
- package/dist/api/compiler/checker-types.js +1874 -0
- package/dist/api/compiler/checker-unused.d.ts +19 -0
- package/dist/api/compiler/checker-unused.js +524 -0
- package/dist/api/compiler/checker-utilities.d.ts +33 -0
- package/dist/api/compiler/checker-utilities.js +141 -0
- package/dist/api/compiler/checker.d.ts +512 -0
- package/dist/api/compiler/checker.js +932 -0
- package/dist/api/compiler/command-line.d.ts +32 -0
- package/dist/api/compiler/command-line.js +383 -0
- package/dist/api/compiler/compile-program.d.ts +118 -0
- package/dist/api/compiler/compile-program.js +384 -0
- package/dist/api/compiler/diagnostic-locales.d.ts +22 -0
- package/dist/api/compiler/diagnostic-locales.js +64 -0
- package/dist/api/compiler/diagnostic-messages.d.ts +2166 -0
- package/dist/api/compiler/diagnostic-messages.js +184 -0
- package/dist/api/compiler/diagnostics.d.ts +161 -0
- package/dist/api/compiler/diagnostics.js +784 -0
- package/dist/api/compiler/emitter.d.ts +71 -0
- package/dist/api/compiler/emitter.js +327 -0
- package/dist/api/compiler/file-include.d.ts +144 -0
- package/dist/api/compiler/file-include.js +599 -0
- package/dist/api/compiler/file-loader.d.ts +290 -0
- package/dist/api/compiler/file-loader.js +1323 -0
- package/dist/api/compiler/file-system.d.ts +51 -0
- package/dist/api/compiler/file-system.js +132 -0
- package/dist/api/compiler/flow.d.ts +60 -0
- package/dist/api/compiler/flow.js +45 -0
- package/dist/api/compiler/instantiation.d.ts +74 -0
- package/dist/api/compiler/instantiation.js +835 -0
- package/dist/api/compiler/jsdoc.d.ts +75 -0
- package/dist/api/compiler/jsdoc.js +1229 -0
- package/dist/api/compiler/link-tables.d.ts +105 -0
- package/dist/api/compiler/link-tables.js +319 -0
- package/dist/api/compiler/locale-data.d.ts +24 -0
- package/dist/api/compiler/locale-data.js +183 -0
- package/dist/api/compiler/locale.d.ts +4 -0
- package/dist/api/compiler/locale.js +317 -0
- package/dist/api/compiler/locales/cs-CZ.d.ts +2 -0
- package/dist/api/compiler/locales/cs-CZ.js +3 -0
- package/dist/api/compiler/locales/de-DE.d.ts +2 -0
- package/dist/api/compiler/locales/de-DE.js +3 -0
- package/dist/api/compiler/locales/es-ES.d.ts +2 -0
- package/dist/api/compiler/locales/es-ES.js +3 -0
- package/dist/api/compiler/locales/fr-FR.d.ts +2 -0
- package/dist/api/compiler/locales/fr-FR.js +3 -0
- package/dist/api/compiler/locales/it-IT.d.ts +2 -0
- package/dist/api/compiler/locales/it-IT.js +3 -0
- package/dist/api/compiler/locales/ja-JP.d.ts +2 -0
- package/dist/api/compiler/locales/ja-JP.js +3 -0
- package/dist/api/compiler/locales/ko-KR.d.ts +2 -0
- package/dist/api/compiler/locales/ko-KR.js +3 -0
- package/dist/api/compiler/locales/pl-PL.d.ts +2 -0
- package/dist/api/compiler/locales/pl-PL.js +3 -0
- package/dist/api/compiler/locales/pt-BR.d.ts +2 -0
- package/dist/api/compiler/locales/pt-BR.js +3 -0
- package/dist/api/compiler/locales/ru-RU.d.ts +2 -0
- package/dist/api/compiler/locales/ru-RU.js +3 -0
- package/dist/api/compiler/locales/tr-TR.d.ts +2 -0
- package/dist/api/compiler/locales/tr-TR.js +3 -0
- package/dist/api/compiler/locales/zh-CN.d.ts +2 -0
- package/dist/api/compiler/locales/zh-CN.js +3 -0
- package/dist/api/compiler/locales/zh-TW.d.ts +2 -0
- package/dist/api/compiler/locales/zh-TW.js +3 -0
- package/dist/api/compiler/module-resolution-types.d.ts +83 -0
- package/dist/api/compiler/module-resolution-types.js +176 -0
- package/dist/api/compiler/module-resolution.d.ts +71 -0
- package/dist/api/compiler/module-resolution.js +1598 -0
- package/dist/api/compiler/module-specifiers.d.ts +64 -0
- package/dist/api/compiler/module-specifiers.js +1101 -0
- package/dist/api/compiler/name-resolver.d.ts +43 -0
- package/dist/api/compiler/name-resolver.js +509 -0
- package/dist/api/compiler/node-builder-names.d.ts +32 -0
- package/dist/api/compiler/node-builder-names.js +854 -0
- package/dist/api/compiler/node-builder-pseudo.d.ts +36 -0
- package/dist/api/compiler/node-builder-pseudo.js +745 -0
- package/dist/api/compiler/node-builder-reuse.d.ts +4 -0
- package/dist/api/compiler/node-builder-reuse.js +647 -0
- package/dist/api/compiler/node-builder.d.ts +270 -0
- package/dist/api/compiler/node-builder.js +2645 -0
- package/dist/api/compiler/option-declarations.d.ts +90 -0
- package/dist/api/compiler/option-declarations.js +1460 -0
- package/dist/api/compiler/options.d.ts +289 -0
- package/dist/api/compiler/options.js +1197 -0
- package/dist/api/compiler/output-paths.d.ts +42 -0
- package/dist/api/compiler/output-paths.js +195 -0
- package/dist/api/compiler/package-json.d.ts +175 -0
- package/dist/api/compiler/package-json.js +1015 -0
- package/dist/api/compiler/parallel-parse.d.ts +221 -0
- package/dist/api/compiler/parallel-parse.js +541 -0
- package/dist/api/compiler/parser.d.ts +604 -0
- package/dist/api/compiler/parser.js +6426 -0
- package/dist/api/compiler/path.d.ts +91 -0
- package/dist/api/compiler/path.js +705 -0
- package/dist/api/compiler/printer/async-helpers.d.ts +22 -0
- package/dist/api/compiler/printer/async-helpers.js +91 -0
- package/dist/api/compiler/printer/auto-generate.d.ts +13 -0
- package/dist/api/compiler/printer/auto-generate.js +20 -0
- package/dist/api/compiler/printer/decorator-helpers.d.ts +24 -0
- package/dist/api/compiler/printer/decorator-helpers.js +118 -0
- package/dist/api/compiler/printer/emit-context.d.ts +157 -0
- package/dist/api/compiler/printer/emit-context.js +582 -0
- package/dist/api/compiler/printer/emit-flags.d.ts +60 -0
- package/dist/api/compiler/printer/emit-flags.js +2 -0
- package/dist/api/compiler/printer/factory-base.d.ts +171 -0
- package/dist/api/compiler/printer/factory-base.js +1505 -0
- package/dist/api/compiler/printer/factory.d.ts +147 -0
- package/dist/api/compiler/printer/factory.js +542 -0
- package/dist/api/compiler/printer/helpers.d.ts +27 -0
- package/dist/api/compiler/printer/helpers.js +164 -0
- package/dist/api/compiler/printer/name-generator.d.ts +41 -0
- package/dist/api/compiler/printer/name-generator.js +283 -0
- package/dist/api/compiler/printer/printer.d.ts +411 -0
- package/dist/api/compiler/printer/printer.js +4517 -0
- package/dist/api/compiler/printer/text-writer.d.ts +46 -0
- package/dist/api/compiler/printer/text-writer.js +172 -0
- package/dist/api/compiler/printer/utilities.d.ts +82 -0
- package/dist/api/compiler/printer/utilities.js +817 -0
- package/dist/api/compiler/program-checker.d.ts +156 -0
- package/dist/api/compiler/program-checker.js +529 -0
- package/dist/api/compiler/program-utilities.d.ts +52 -0
- package/dist/api/compiler/program-utilities.js +365 -0
- package/dist/api/compiler/program.d.ts +180 -0
- package/dist/api/compiler/program.js +1019 -0
- package/dist/api/compiler/pseudo-bigint.d.ts +5 -0
- package/dist/api/compiler/pseudo-bigint.js +61 -0
- package/dist/api/compiler/regexp-checker.d.ts +38 -0
- package/dist/api/compiler/regexp-checker.js +942 -0
- package/dist/api/compiler/relations.d.ts +263 -0
- package/dist/api/compiler/relations.js +4002 -0
- package/dist/api/compiler/reparser.d.ts +48 -0
- package/dist/api/compiler/reparser.js +1323 -0
- package/dist/api/compiler/scanner.d.ts +256 -0
- package/dist/api/compiler/scanner.js +2853 -0
- package/dist/api/compiler/side-state.d.ts +16 -0
- package/dist/api/compiler/side-state.js +89 -0
- package/dist/api/compiler/sourcemap.d.ts +55 -0
- package/dist/api/compiler/sourcemap.js +340 -0
- package/dist/api/compiler/spelling.d.ts +14 -0
- package/dist/api/compiler/spelling.js +128 -0
- package/dist/api/compiler/symbol-accessibility.d.ts +57 -0
- package/dist/api/compiler/symbol-accessibility.js +991 -0
- package/dist/api/compiler/symbol.d.ts +282 -0
- package/dist/api/compiler/symbol.js +339 -0
- package/dist/api/compiler/symlinks.d.ts +32 -0
- package/dist/api/compiler/symlinks.js +114 -0
- package/dist/api/compiler/syntax-kind.d.ts +389 -0
- package/dist/api/compiler/syntax-kind.js +2 -0
- package/dist/api/compiler/timeline.d.ts +9 -0
- package/dist/api/compiler/timeline.js +54 -0
- package/dist/api/compiler/transformers/alias-references.d.ts +39 -0
- package/dist/api/compiler/transformers/alias-references.js +677 -0
- package/dist/api/compiler/transformers/async-utilities.d.ts +51 -0
- package/dist/api/compiler/transformers/async-utilities.js +260 -0
- package/dist/api/compiler/transformers/async.d.ts +53 -0
- package/dist/api/compiler/transformers/async.js +645 -0
- package/dist/api/compiler/transformers/class-fields.d.ts +206 -0
- package/dist/api/compiler/transformers/class-fields.js +2418 -0
- package/dist/api/compiler/transformers/class-utilities.d.ts +46 -0
- package/dist/api/compiler/transformers/class-utilities.js +261 -0
- package/dist/api/compiler/transformers/commonjs-module.d.ts +103 -0
- package/dist/api/compiler/transformers/commonjs-module.js +1180 -0
- package/dist/api/compiler/transformers/const-enum-inliner.d.ts +11 -0
- package/dist/api/compiler/transformers/const-enum-inliner.js +36 -0
- package/dist/api/compiler/transformers/declarations-diagnostics.d.ts +52 -0
- package/dist/api/compiler/transformers/declarations-diagnostics.js +539 -0
- package/dist/api/compiler/transformers/declarations-pseudo.d.ts +160 -0
- package/dist/api/compiler/transformers/declarations-pseudo.js +799 -0
- package/dist/api/compiler/transformers/declarations-resolver.d.ts +152 -0
- package/dist/api/compiler/transformers/declarations-resolver.js +35 -0
- package/dist/api/compiler/transformers/declarations-syntactic.d.ts +119 -0
- package/dist/api/compiler/transformers/declarations-syntactic.js +1582 -0
- package/dist/api/compiler/transformers/declarations-tracker.d.ts +46 -0
- package/dist/api/compiler/transformers/declarations-tracker.js +198 -0
- package/dist/api/compiler/transformers/declarations.d.ts +175 -0
- package/dist/api/compiler/transformers/declarations.js +2381 -0
- package/dist/api/compiler/transformers/decorator-metadata.d.ts +54 -0
- package/dist/api/compiler/transformers/decorator-metadata.js +554 -0
- package/dist/api/compiler/transformers/decorator-utilities.d.ts +38 -0
- package/dist/api/compiler/transformers/decorator-utilities.js +238 -0
- package/dist/api/compiler/transformers/destructuring.d.ts +25 -0
- package/dist/api/compiler/transformers/destructuring.js +626 -0
- package/dist/api/compiler/transformers/downlevel.d.ts +6 -0
- package/dist/api/compiler/transformers/downlevel.js +45 -0
- package/dist/api/compiler/transformers/emit-resolver.d.ts +61 -0
- package/dist/api/compiler/transformers/emit-resolver.js +197 -0
- package/dist/api/compiler/transformers/es-decorators.d.ts +118 -0
- package/dist/api/compiler/transformers/es-decorators.js +1901 -0
- package/dist/api/compiler/transformers/exponentiation.d.ts +11 -0
- package/dist/api/compiler/transformers/exponentiation.js +76 -0
- package/dist/api/compiler/transformers/external-module-info.d.ts +35 -0
- package/dist/api/compiler/transformers/external-module-info.js +351 -0
- package/dist/api/compiler/transformers/for-await.d.ts +43 -0
- package/dist/api/compiler/transformers/for-await.js +469 -0
- package/dist/api/compiler/transformers/import-elision.d.ts +16 -0
- package/dist/api/compiler/transformers/import-elision.js +124 -0
- package/dist/api/compiler/transformers/jsx-entities.d.ts +1 -0
- package/dist/api/compiler/transformers/jsx-entities.js +256 -0
- package/dist/api/compiler/transformers/jsx.d.ts +71 -0
- package/dist/api/compiler/transformers/jsx.js +700 -0
- package/dist/api/compiler/transformers/legacy-decorators.d.ts +56 -0
- package/dist/api/compiler/transformers/legacy-decorators.js +564 -0
- package/dist/api/compiler/transformers/logical-assignment.d.ts +14 -0
- package/dist/api/compiler/transformers/logical-assignment.js +62 -0
- package/dist/api/compiler/transformers/module-utilities.d.ts +9 -0
- package/dist/api/compiler/transformers/module-utilities.js +36 -0
- package/dist/api/compiler/transformers/module.d.ts +49 -0
- package/dist/api/compiler/transformers/module.js +296 -0
- package/dist/api/compiler/transformers/named-evaluation.d.ts +26 -0
- package/dist/api/compiler/transformers/named-evaluation.js +266 -0
- package/dist/api/compiler/transformers/nullish-coalescing.d.ts +9 -0
- package/dist/api/compiler/transformers/nullish-coalescing.js +26 -0
- package/dist/api/compiler/transformers/object-rest-spread.d.ts +34 -0
- package/dist/api/compiler/transformers/object-rest-spread.js +411 -0
- package/dist/api/compiler/transformers/optional-catch.d.ts +9 -0
- package/dist/api/compiler/transformers/optional-catch.js +20 -0
- package/dist/api/compiler/transformers/optional-chain.d.ts +14 -0
- package/dist/api/compiler/transformers/optional-chain.js +188 -0
- package/dist/api/compiler/transformers/reference-resolver.d.ts +129 -0
- package/dist/api/compiler/transformers/reference-resolver.js +1157 -0
- package/dist/api/compiler/transformers/runtime-syntax.d.ts +71 -0
- package/dist/api/compiler/transformers/runtime-syntax.js +753 -0
- package/dist/api/compiler/transformers/subtree-facts.d.ts +10 -0
- package/dist/api/compiler/transformers/subtree-facts.js +205 -0
- package/dist/api/compiler/transformers/syntax-facts.d.ts +52 -0
- package/dist/api/compiler/transformers/syntax-facts.js +258 -0
- package/dist/api/compiler/transformers/tagged-template.d.ts +17 -0
- package/dist/api/compiler/transformers/tagged-template.js +148 -0
- package/dist/api/compiler/transformers/transformer.d.ts +17 -0
- package/dist/api/compiler/transformers/transformer.js +54 -0
- package/dist/api/compiler/transformers/type-eraser.d.ts +21 -0
- package/dist/api/compiler/transformers/type-eraser.js +346 -0
- package/dist/api/compiler/transformers/type-serialization.d.ts +20 -0
- package/dist/api/compiler/transformers/type-serialization.js +347 -0
- package/dist/api/compiler/transformers/using.d.ts +56 -0
- package/dist/api/compiler/transformers/using.js +453 -0
- package/dist/api/compiler/transformers/utilities.d.ts +50 -0
- package/dist/api/compiler/transformers/utilities.js +347 -0
- package/dist/api/compiler/transformers/visitor-base.d.ts +6 -0
- package/dist/api/compiler/transformers/visitor-base.js +817 -0
- package/dist/api/compiler/transformers/visitor-hooks.d.ts +29 -0
- package/dist/api/compiler/transformers/visitor-hooks.js +189 -0
- package/dist/api/compiler/tsconfig.d.ts +177 -0
- package/dist/api/compiler/tsconfig.js +1311 -0
- package/dist/api/compiler/type-printer.d.ts +15 -0
- package/dist/api/compiler/type-printer.js +74 -0
- package/dist/api/compiler/types.d.ts +87 -0
- package/dist/api/compiler/types.js +23 -0
- package/dist/api/compiler/unicode-identifiers.d.ts +2 -0
- package/dist/api/compiler/unicode-identifiers.js +209 -0
- package/dist/api/compiler/unicode-properties.d.ts +8 -0
- package/dist/api/compiler/unicode-properties.js +531 -0
- package/dist/api/compiler/vfs-match.d.ts +24 -0
- package/dist/api/compiler/vfs-match.js +587 -0
- package/dist/api/library/ast.d.ts +3 -2
- package/dist/api/library/ast.generated.d.ts +127 -139
- package/dist/api/library/checker.d.ts +51 -0
- package/dist/api/library/checker.js +318 -0
- package/dist/api/library/diagnostics.d.ts +13 -0
- package/dist/api/library/diagnostics.js +50 -0
- package/dist/api/library/disk.d.ts +13 -0
- package/dist/api/library/disk.js +66 -0
- package/dist/api/library/errors.d.ts +13 -0
- package/dist/api/library/errors.js +24 -0
- package/dist/api/library/host.d.ts +24 -0
- package/dist/api/library/host.js +52 -0
- package/dist/api/library/index.d.ts +5 -1
- package/dist/api/library/index.js +4 -0
- package/dist/api/library/nodes.d.ts +51 -0
- package/dist/api/library/nodes.js +196 -0
- package/dist/api/library/options.d.ts +144 -0
- package/dist/api/library/options.js +308 -0
- package/dist/api/library/parse.d.ts +19 -0
- package/dist/api/library/parse.js +41 -0
- package/dist/api/library/program.d.ts +21 -0
- package/dist/api/library/program.js +234 -0
- package/dist/api/library/types.d.ts +14 -1
- package/package.json +12 -8
- package/src/compiler/ast-utilities.ts +548 -0
- package/src/compiler/ast.ts +12870 -0
- package/src/compiler/astnav.ts +799 -0
- package/src/compiler/binder-utilities.ts +1392 -0
- package/src/compiler/binder.ts +2707 -0
- package/src/compiler/build-info.ts +1197 -0
- package/src/compiler/character-codes.ts +323 -0
- package/src/compiler/checker-calls.ts +2155 -0
- package/src/compiler/checker-classes.ts +706 -0
- package/src/compiler/checker-contextual.ts +1457 -0
- package/src/compiler/checker-declaration-order.ts +438 -0
- package/src/compiler/checker-declarations.ts +1201 -0
- package/src/compiler/checker-declared-types.ts +919 -0
- package/src/compiler/checker-decorators.ts +694 -0
- package/src/compiler/checker-deprecation.ts +355 -0
- package/src/compiler/checker-destructuring.ts +805 -0
- package/src/compiler/checker-elaboration.ts +477 -0
- package/src/compiler/checker-emit-helpers.ts +224 -0
- package/src/compiler/checker-emit-resolver.ts +769 -0
- package/src/compiler/checker-evaluator.ts +243 -0
- package/src/compiler/checker-expressions.ts +1831 -0
- package/src/compiler/checker-features.ts +361 -0
- package/src/compiler/checker-flow.ts +394 -0
- package/src/compiler/checker-functions.ts +1296 -0
- package/src/compiler/checker-generated-code.ts +227 -0
- package/src/compiler/checker-globals.ts +52 -0
- package/src/compiler/checker-grammar.ts +3596 -0
- package/src/compiler/checker-heritage.ts +1240 -0
- package/src/compiler/checker-inference.ts +2584 -0
- package/src/compiler/checker-iteration.ts +1206 -0
- package/src/compiler/checker-javascript.ts +502 -0
- package/src/compiler/checker-jsdoc.ts +360 -0
- package/src/compiler/checker-jsx.ts +1928 -0
- package/src/compiler/checker-literals.ts +61 -0
- package/src/compiler/checker-members.ts +2480 -0
- package/src/compiler/checker-modules.ts +2896 -0
- package/src/compiler/checker-narrowing.ts +3230 -0
- package/src/compiler/checker-object-literals.ts +591 -0
- package/src/compiler/checker-operators.ts +1422 -0
- package/src/compiler/checker-overloads.ts +328 -0
- package/src/compiler/checker-property-access.ts +906 -0
- package/src/compiler/checker-services.ts +1149 -0
- package/src/compiler/checker-signatures.ts +1032 -0
- package/src/compiler/checker-source-file.ts +732 -0
- package/src/compiler/checker-statements.ts +292 -0
- package/src/compiler/checker-super.ts +261 -0
- package/src/compiler/checker-symbol-types.ts +1187 -0
- package/src/compiler/checker-symbols.ts +2157 -0
- package/src/compiler/checker-type-factory.ts +2616 -0
- package/src/compiler/checker-type-nodes.ts +1033 -0
- package/src/compiler/checker-type-operators.ts +2510 -0
- package/src/compiler/checker-types.ts +2520 -0
- package/src/compiler/checker-unused.ts +642 -0
- package/src/compiler/checker-utilities.ts +161 -0
- package/src/compiler/checker.ts +1138 -0
- package/src/compiler/command-line.ts +436 -0
- package/src/compiler/compile-program.ts +439 -0
- package/src/compiler/decoder.ts +1209 -0
- package/src/compiler/diagnostic-locales.ts +86 -0
- package/src/compiler/diagnostic-messages.ts +2349 -0
- package/src/compiler/diagnostics.ts +858 -0
- package/src/compiler/emitter.ts +434 -0
- package/src/compiler/encoder.ts +1945 -0
- package/src/compiler/file-include.ts +741 -0
- package/src/compiler/file-loader.ts +1597 -0
- package/src/compiler/file-system.ts +143 -0
- package/src/compiler/flow.ts +89 -0
- package/src/compiler/help.ts +473 -0
- package/src/compiler/incremental.ts +2818 -0
- package/src/compiler/init.ts +141 -0
- package/src/compiler/instantiation.ts +938 -0
- package/src/compiler/jsdoc.ts +1386 -0
- package/src/compiler/link-tables.ts +343 -0
- package/src/compiler/locale-data.ts +203 -0
- package/src/compiler/locale.ts +307 -0
- package/src/compiler/locales/cs-CZ.ts +5 -0
- package/src/compiler/locales/de-DE.ts +5 -0
- package/src/compiler/locales/es-ES.ts +5 -0
- package/src/compiler/locales/fr-FR.ts +5 -0
- package/src/compiler/locales/it-IT.ts +5 -0
- package/src/compiler/locales/ja-JP.ts +5 -0
- package/src/compiler/locales/ko-KR.ts +5 -0
- package/src/compiler/locales/pl-PL.ts +5 -0
- package/src/compiler/locales/pt-BR.ts +5 -0
- package/src/compiler/locales/ru-RU.ts +5 -0
- package/src/compiler/locales/tr-TR.ts +5 -0
- package/src/compiler/locales/zh-CN.ts +5 -0
- package/src/compiler/locales/zh-TW.ts +5 -0
- package/src/compiler/module-resolution-types.ts +243 -0
- package/src/compiler/module-resolution.ts +2072 -0
- package/src/compiler/module-specifiers.ts +1491 -0
- package/src/compiler/name-resolver.ts +646 -0
- package/src/compiler/node-builder-names.ts +1071 -0
- package/src/compiler/node-builder-pseudo.ts +892 -0
- package/src/compiler/node-builder-reuse.ts +764 -0
- package/src/compiler/node-builder.ts +3433 -0
- package/src/compiler/option-declarations.ts +1560 -0
- package/src/compiler/options.ts +1576 -0
- package/src/compiler/output-paths.ts +334 -0
- package/src/compiler/package-json.ts +1083 -0
- package/src/compiler/parallel-check.ts +1954 -0
- package/src/compiler/parallel-parse.ts +595 -0
- package/src/compiler/parse-thread.ts +136 -0
- package/src/compiler/parser.ts +7766 -0
- package/src/compiler/path.ts +717 -0
- package/src/compiler/printer/async-helpers.ts +183 -0
- package/src/compiler/printer/auto-generate.ts +27 -0
- package/src/compiler/printer/decorator-helpers.ts +218 -0
- package/src/compiler/printer/emit-context.ts +684 -0
- package/src/compiler/printer/emit-flags.ts +64 -0
- package/src/compiler/printer/factory-base.ts +2577 -0
- package/src/compiler/printer/factory.ts +764 -0
- package/src/compiler/printer/helpers.ts +291 -0
- package/src/compiler/printer/name-generator.ts +372 -0
- package/src/compiler/printer/printer.ts +5072 -0
- package/src/compiler/printer/text-writer.ts +183 -0
- package/src/compiler/printer/utilities.ts +884 -0
- package/src/compiler/program-checker.ts +594 -0
- package/src/compiler/program-utilities.ts +435 -0
- package/src/compiler/program.ts +1426 -0
- package/src/compiler/pseudo-bigint.ts +62 -0
- package/src/compiler/regexp-checker.ts +1142 -0
- package/src/compiler/relations.ts +5149 -0
- package/src/compiler/reparser.ts +1566 -0
- package/src/compiler/scanner.ts +2951 -0
- package/src/compiler/show-config.ts +239 -0
- package/src/compiler/side-state.ts +125 -0
- package/src/compiler/sourcemap.ts +366 -0
- package/src/compiler/spelling.ts +122 -0
- package/src/compiler/symbol-accessibility.ts +1166 -0
- package/src/compiler/symbol.ts +557 -0
- package/src/compiler/symlinks.ts +137 -0
- package/src/compiler/syntax-kind.ts +391 -0
- package/src/compiler/thread-entry.ts +191 -0
- package/src/compiler/timeline.ts +53 -0
- package/src/compiler/transformers/alias-references.ts +757 -0
- package/src/compiler/transformers/async-utilities.ts +335 -0
- package/src/compiler/transformers/async.ts +838 -0
- package/src/compiler/transformers/class-fields.ts +2967 -0
- package/src/compiler/transformers/class-utilities.ts +324 -0
- package/src/compiler/transformers/commonjs-module.ts +1621 -0
- package/src/compiler/transformers/const-enum-inliner.ts +50 -0
- package/src/compiler/transformers/declarations-diagnostics.ts +833 -0
- package/src/compiler/transformers/declarations-pseudo.ts +969 -0
- package/src/compiler/transformers/declarations-resolver.ts +249 -0
- package/src/compiler/transformers/declarations-syntactic.ts +1867 -0
- package/src/compiler/transformers/declarations-tracker.ts +269 -0
- package/src/compiler/transformers/declarations.ts +3120 -0
- package/src/compiler/transformers/decorator-metadata.ts +697 -0
- package/src/compiler/transformers/decorator-utilities.ts +283 -0
- package/src/compiler/transformers/destructuring.ts +708 -0
- package/src/compiler/transformers/downlevel.ts +50 -0
- package/src/compiler/transformers/emit-resolver.ts +258 -0
- package/src/compiler/transformers/es-decorators.ts +2682 -0
- package/src/compiler/transformers/exponentiation.ts +80 -0
- package/src/compiler/transformers/external-module-info.ts +412 -0
- package/src/compiler/transformers/for-await.ts +687 -0
- package/src/compiler/transformers/import-elision.ts +152 -0
- package/src/compiler/transformers/jsx-entities.ts +256 -0
- package/src/compiler/transformers/jsx.ts +824 -0
- package/src/compiler/transformers/legacy-decorators.ts +726 -0
- package/src/compiler/transformers/logical-assignment.ts +75 -0
- package/src/compiler/transformers/module-utilities.ts +42 -0
- package/src/compiler/transformers/module.ts +474 -0
- package/src/compiler/transformers/named-evaluation.ts +389 -0
- package/src/compiler/transformers/nullish-coalescing.ts +35 -0
- package/src/compiler/transformers/object-rest-spread.ts +577 -0
- package/src/compiler/transformers/optional-catch.ts +29 -0
- package/src/compiler/transformers/optional-chain.ts +246 -0
- package/src/compiler/transformers/reference-resolver.ts +1213 -0
- package/src/compiler/transformers/runtime-syntax.ts +942 -0
- package/src/compiler/transformers/subtree-facts.ts +253 -0
- package/src/compiler/transformers/syntax-facts.ts +358 -0
- package/src/compiler/transformers/tagged-template.ts +167 -0
- package/src/compiler/transformers/transformer.ts +56 -0
- package/src/compiler/transformers/type-eraser.ts +520 -0
- package/src/compiler/transformers/type-serialization.ts +374 -0
- package/src/compiler/transformers/using.ts +613 -0
- package/src/compiler/transformers/utilities.ts +419 -0
- package/src/compiler/transformers/visitor-base.ts +1601 -0
- package/src/compiler/transformers/visitor-hooks.ts +252 -0
- package/src/compiler/tsc-build.ts +1422 -0
- package/src/compiler/tsc-cli.ts +669 -0
- package/src/compiler/tsc-compile.ts +446 -0
- package/src/compiler/tsc-watch.ts +922 -0
- package/src/compiler/tsconfig.ts +1574 -0
- package/src/compiler/type-printer.ts +110 -0
- package/src/compiler/types.ts +115 -0
- package/src/compiler/unicode-identifiers.ts +212 -0
- package/src/compiler/unicode-properties.ts +537 -0
- package/src/compiler/vfs-match.ts +597 -0
- package/src/compiler/xxh3.ts +650 -0
- package/src/library/ast.generated.ts +141 -167
- package/src/library/ast.ts +4 -1
- package/src/library/checker.ts +384 -0
- package/src/library/diagnostics.ts +72 -0
- package/src/library/disk.ts +73 -0
- package/src/library/errors.ts +26 -0
- package/src/library/host.ts +63 -0
- package/src/library/index.ts +21 -0
- package/src/library/nodes.ts +232 -0
- package/src/library/options.ts +449 -0
- package/src/library/parse.ts +63 -0
- package/src/library/program.ts +293 -0
- package/src/library/types.ts +14 -1
|
@@ -0,0 +1,1928 @@
|
|
|
1
|
+
// JSX: element and fragment types, the `JSX` namespace, intrinsic elements, attributes and children.
|
|
2
|
+
import { checkDeprecatedJsxAttribute, checkDeprecatedSignature } from './checker-deprecation.js';
|
|
3
|
+
import {
|
|
4
|
+
type BinaryExpression,
|
|
5
|
+
type JsxAttribute,
|
|
6
|
+
type JsxAttributes,
|
|
7
|
+
type JsxElement,
|
|
8
|
+
type JsxExpression,
|
|
9
|
+
type JsxFragment,
|
|
10
|
+
type JsxNamespacedName,
|
|
11
|
+
type JsxOpeningElement,
|
|
12
|
+
type JsxSelfClosingElement,
|
|
13
|
+
type JsxSpreadAttribute,
|
|
14
|
+
type JsxText,
|
|
15
|
+
type Node,
|
|
16
|
+
type NodeList,
|
|
17
|
+
type PropertyAccessExpression,
|
|
18
|
+
type QualifiedName,
|
|
19
|
+
type SourceFile,
|
|
20
|
+
getSymbol,
|
|
21
|
+
getTagName,
|
|
22
|
+
getText,
|
|
23
|
+
getTypeArguments,
|
|
24
|
+
getExpression,
|
|
25
|
+
Identifier,
|
|
26
|
+
PropertySignatureDeclaration,
|
|
27
|
+
} from './ast.js';
|
|
28
|
+
import { getSourceFileOfNode, getSourceTextOfNode } from './binder-utilities.js';
|
|
29
|
+
import { Diagnostic, type DiagnosticMessage, Diagnostics, chainDiagnostic } from './diagnostics.js';
|
|
30
|
+
import { JsxEmit } from './options.js';
|
|
31
|
+
import { parseIsolatedEntityName } from './parser.js';
|
|
32
|
+
import { skipTrivia } from './scanner.js';
|
|
33
|
+
import { SyntaxKind } from './syntax-kind.js';
|
|
34
|
+
import { type Checker, createDiagnosticForNode } from './checker.js';
|
|
35
|
+
import {
|
|
36
|
+
AccessFlags,
|
|
37
|
+
CheckMode,
|
|
38
|
+
type LiteralType,
|
|
39
|
+
ObjectFlags,
|
|
40
|
+
type Signature,
|
|
41
|
+
SignatureFlags,
|
|
42
|
+
SignatureKind,
|
|
43
|
+
type Type,
|
|
44
|
+
TypeFlags,
|
|
45
|
+
newTypeMapper,
|
|
46
|
+
} from './checker-types.js';
|
|
47
|
+
import {
|
|
48
|
+
createAnonymousType,
|
|
49
|
+
createArrayType,
|
|
50
|
+
createTupleType,
|
|
51
|
+
createTypeReference,
|
|
52
|
+
getIntersectionType,
|
|
53
|
+
getPropagatingFlagsOfTypes,
|
|
54
|
+
getStringLiteralType,
|
|
55
|
+
getUnionType,
|
|
56
|
+
intersectTypes,
|
|
57
|
+
isErrorType,
|
|
58
|
+
everyType,
|
|
59
|
+
isArrayType,
|
|
60
|
+
mapTypeEx,
|
|
61
|
+
someType,
|
|
62
|
+
typesOf,
|
|
63
|
+
} from './checker-type-factory.js';
|
|
64
|
+
import {
|
|
65
|
+
getApparentType,
|
|
66
|
+
getApplicableIndexInfo,
|
|
67
|
+
getApplicableIndexInfoForName,
|
|
68
|
+
getIndexTypeOfType,
|
|
69
|
+
getPropertiesOfType,
|
|
70
|
+
getPropertyOfType,
|
|
71
|
+
getSignaturesOfType,
|
|
72
|
+
getTypeOfPropertyOfType,
|
|
73
|
+
getUnionSignatures,
|
|
74
|
+
isArrayLikeType,
|
|
75
|
+
} from './checker-members.js';
|
|
76
|
+
import {
|
|
77
|
+
getMergedSymbol,
|
|
78
|
+
getExportsOfSymbol,
|
|
79
|
+
getFirstIdentifier,
|
|
80
|
+
getGlobalSymbol,
|
|
81
|
+
getSymbolOfMeaning,
|
|
82
|
+
resolveAlias,
|
|
83
|
+
resolveEntityName,
|
|
84
|
+
getSpellingSuggestionForName,
|
|
85
|
+
resolveName,
|
|
86
|
+
resolveSymbol,
|
|
87
|
+
} from './checker-symbols.js';
|
|
88
|
+
import { resolveExternalModule } from './checker-modules.js';
|
|
89
|
+
import {
|
|
90
|
+
fillMissingTypeArguments,
|
|
91
|
+
getDeclaredTypeOfSymbol,
|
|
92
|
+
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
|
|
93
|
+
getMinTypeArgumentCount,
|
|
94
|
+
} from './checker-declared-types.js';
|
|
95
|
+
import { getTypeAliasInstantiation } from './checker-type-nodes.js';
|
|
96
|
+
import { getTypeOfSymbol } from './checker-symbol-types.js';
|
|
97
|
+
import {
|
|
98
|
+
getMinArgumentCount,
|
|
99
|
+
getOrCreateTypeFromSignature,
|
|
100
|
+
getParameterCount,
|
|
101
|
+
getReturnTypeOfSignature,
|
|
102
|
+
getTypeAtPosition,
|
|
103
|
+
hasEffectiveRestParameter,
|
|
104
|
+
} from './checker-signatures.js';
|
|
105
|
+
import { instantiateType } from './instantiation.js';
|
|
106
|
+
import {
|
|
107
|
+
checkTypeRelatedTo,
|
|
108
|
+
getRegularTypeOfObjectLiteral,
|
|
109
|
+
isExactOptionalPropertyMismatch,
|
|
110
|
+
isTypeRelatedTo,
|
|
111
|
+
type Relation,
|
|
112
|
+
} from './relations.js';
|
|
113
|
+
import {
|
|
114
|
+
checkExpression,
|
|
115
|
+
checkExpressionCached,
|
|
116
|
+
checkExpressionEx,
|
|
117
|
+
checkExpressionForMutableLocationEx,
|
|
118
|
+
} from './checker-expressions.js';
|
|
119
|
+
import {
|
|
120
|
+
ContextFlags,
|
|
121
|
+
checkExpressionWithContextualType,
|
|
122
|
+
findContextualNode,
|
|
123
|
+
getApparentTypeOfContextualType,
|
|
124
|
+
getApparentTypeOfContextualTypeEx,
|
|
125
|
+
getContextualType,
|
|
126
|
+
getContextualTypeEx,
|
|
127
|
+
getTypeOfPropertyOfContextualType,
|
|
128
|
+
getInferenceContext,
|
|
129
|
+
} from './checker-contextual.js';
|
|
130
|
+
import { checkNodeDeferred, checkSourceElement } from './checker-source-file.js';
|
|
131
|
+
import { getResolvedSignature, resolveCall } from './checker-calls.js';
|
|
132
|
+
import {
|
|
133
|
+
type InferenceContext,
|
|
134
|
+
InferencePriority,
|
|
135
|
+
addIntraExpressionInferenceSite,
|
|
136
|
+
getInferredTypes,
|
|
137
|
+
inferTypes,
|
|
138
|
+
} from './checker-inference.js';
|
|
139
|
+
import { isContextSensitive } from './checker-functions.js';
|
|
140
|
+
import { checkSpreadPropOverrides, getSpreadType } from './checker-object-literals.js';
|
|
141
|
+
import { isValidSpreadType } from './checker-destructuring.js';
|
|
142
|
+
import {
|
|
143
|
+
checkExpressionForMutableLocationWithContextualType,
|
|
144
|
+
checkTypeRelatedToAndOptionallyElaborate,
|
|
145
|
+
elaborateElement,
|
|
146
|
+
elaborateError,
|
|
147
|
+
getBestMatchIndexedAccessTypeOrUndefined,
|
|
148
|
+
} from './checker-elaboration.js';
|
|
149
|
+
import {
|
|
150
|
+
IterationTypeKind,
|
|
151
|
+
IterationUse,
|
|
152
|
+
getGlobalIterableType,
|
|
153
|
+
getIterationTypeOfIterable,
|
|
154
|
+
} from './checker-iteration.js';
|
|
155
|
+
import { getIndexedAccessTypeOrUndefined, getPropertyNameFromIndex } from './checker-type-operators.js';
|
|
156
|
+
import { removeMissingType } from './checker-symbol-types.js';
|
|
157
|
+
import { typeToString } from './type-printer.js';
|
|
158
|
+
import { getReducedType } from './checker-members.js';
|
|
159
|
+
import { getNumberLiteralType } from './checker-type-factory.js';
|
|
160
|
+
import { getIndexedAccessType } from './checker-type-operators.js';
|
|
161
|
+
import { filterType, isTupleType } from './checker-type-factory.js';
|
|
162
|
+
import { createTypeFromGenericGlobalType } from './checker-type-factory.js';
|
|
163
|
+
import { isTypeAssignableTo } from './relations.js';
|
|
164
|
+
import {
|
|
165
|
+
copyDeclarations,
|
|
166
|
+
declarationCount,
|
|
167
|
+
getSymbolId,
|
|
168
|
+
InternalSymbolName,
|
|
169
|
+
type Symbol,
|
|
170
|
+
SymbolFlags,
|
|
171
|
+
type SymbolTable,
|
|
172
|
+
} from './symbol.js';
|
|
173
|
+
|
|
174
|
+
const enum JsxFlags {
|
|
175
|
+
None = 0,
|
|
176
|
+
/** An element from a named property of `JSX.IntrinsicElements`. */
|
|
177
|
+
IntrinsicNamedElement = 1 << 0,
|
|
178
|
+
/** An element from the string index signature of `JSX.IntrinsicElements`. */
|
|
179
|
+
IntrinsicIndexedElement = 1 << 1,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const enum JsxReferenceKind {
|
|
183
|
+
Component,
|
|
184
|
+
Function,
|
|
185
|
+
Mixed,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Names in the `JSX` namespace.
|
|
189
|
+
const jsxNamespaceName = 'JSX';
|
|
190
|
+
const jsxIntrinsicElementsName = 'IntrinsicElements';
|
|
191
|
+
const jsxElementClassName = 'ElementClass';
|
|
192
|
+
const jsxElementAttributesPropertyName = 'ElementAttributesProperty';
|
|
193
|
+
const jsxElementChildrenAttributeName = 'ElementChildrenAttribute';
|
|
194
|
+
const jsxElementName = 'Element';
|
|
195
|
+
const jsxElementTypeName = 'ElementType';
|
|
196
|
+
const jsxIntrinsicAttributesName = 'IntrinsicAttributes';
|
|
197
|
+
const jsxIntrinsicClassAttributesName = 'IntrinsicClassAttributes';
|
|
198
|
+
const jsxLibraryManagedAttributesName = 'LibraryManagedAttributes';
|
|
199
|
+
|
|
200
|
+
/** Per-element JSX state. */
|
|
201
|
+
class JsxElementLinks {
|
|
202
|
+
jsxFlags = JsxFlags.None;
|
|
203
|
+
resolvedJsxElementAttributesType: Type | undefined = undefined;
|
|
204
|
+
resolvedSymbol: Symbol | undefined = undefined;
|
|
205
|
+
/** The resolved `JSX` namespace; `unknownSymbol` when the local lookup failed. */
|
|
206
|
+
jsxNamespace: Symbol | undefined = undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Per-file JSX state: pragmas, factories and the implicit runtime import. */
|
|
210
|
+
class JsxFileLinks {
|
|
211
|
+
localJsxNamespace = '';
|
|
212
|
+
localJsxFactory: Node | undefined = undefined;
|
|
213
|
+
localJsxFragmentNamespace = '';
|
|
214
|
+
localJsxFragmentFactory: Node | undefined = undefined;
|
|
215
|
+
jsxFragmentType: Type | undefined = undefined;
|
|
216
|
+
/** `unknownSymbol` when there is no implicit import container. */
|
|
217
|
+
jsxImplicitImportContainer: Symbol | undefined = undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The checker's JSX caches. */
|
|
221
|
+
export class JsxState {
|
|
222
|
+
readonly elementLinks = new Map<Node, JsxElementLinks>();
|
|
223
|
+
readonly fileLinks = new Map<SourceFile, JsxFileLinks>();
|
|
224
|
+
/** getJsxIntrinsicConstructorType by attributes and element type ids. */
|
|
225
|
+
readonly intrinsicConstructorTypes = new Map<string, Type>();
|
|
226
|
+
jsxNamespace = '';
|
|
227
|
+
jsxFactoryEntity: Node | undefined = undefined;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function elementLinks(c: Checker, node: Node): JsxElementLinks {
|
|
231
|
+
let links = c.jsx.elementLinks.get(node);
|
|
232
|
+
if (links === undefined) {
|
|
233
|
+
links = new JsxElementLinks();
|
|
234
|
+
c.jsx.elementLinks.set(node, links);
|
|
235
|
+
}
|
|
236
|
+
return links;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function fileLinks(c: Checker, file: SourceFile): JsxFileLinks {
|
|
240
|
+
let links = c.jsx.fileLinks.get(file);
|
|
241
|
+
if (links === undefined) {
|
|
242
|
+
links = new JsxFileLinks();
|
|
243
|
+
c.jsx.fileLinks.set(file, links);
|
|
244
|
+
}
|
|
245
|
+
return links;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ---- Syntax helpers
|
|
249
|
+
|
|
250
|
+
export function isJsxOpeningLikeElement(node: Node): boolean {
|
|
251
|
+
return node.kind === SyntaxKind.JsxOpeningElement || node.kind === SyntaxKind.JsxSelfClosingElement;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function isIntrinsicJsxName(name: string): boolean {
|
|
255
|
+
if (name.length === 0) return false;
|
|
256
|
+
const ch = name.charCodeAt(0);
|
|
257
|
+
return (ch >= 0x61 && ch <= 0x7a) || name.includes('-');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** Whether a tag name refers to an intrinsic element: a lowercase or dashed identifier, or `ns:name`. */
|
|
261
|
+
export function isJsxIntrinsicTagName(tagName: Node): boolean {
|
|
262
|
+
return (
|
|
263
|
+
(tagName.kind === SyntaxKind.Identifier && isIntrinsicJsxName(getText(tagName))) ||
|
|
264
|
+
tagName.kind === SyntaxKind.JsxNamespacedName
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** The text of an identifier or `ns:name`. */
|
|
269
|
+
function jsxNameText(node: Node): string {
|
|
270
|
+
if (node.kind === SyntaxKind.JsxNamespacedName) {
|
|
271
|
+
const name = node as JsxNamespacedName;
|
|
272
|
+
return name.namespace.text + ':' + name.name.text;
|
|
273
|
+
}
|
|
274
|
+
return getText(node);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function getTextOfNode(node: Node): string {
|
|
278
|
+
return getSourceTextOfNode(getSourceFileOfNode(node), node);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function entityNameToString(node: Node): string {
|
|
282
|
+
switch (node.kind) {
|
|
283
|
+
case SyntaxKind.ThisKeyword:
|
|
284
|
+
return 'this';
|
|
285
|
+
case SyntaxKind.PropertyAccessExpression: {
|
|
286
|
+
const access = node as PropertyAccessExpression;
|
|
287
|
+
return entityNameToString(access.expression) + '.' + entityNameToString(access.name);
|
|
288
|
+
}
|
|
289
|
+
case SyntaxKind.QualifiedName:
|
|
290
|
+
return entityNameToString((node as QualifiedName).left) + '.' + (node as QualifiedName).right.text;
|
|
291
|
+
case SyntaxKind.JsxNamespacedName:
|
|
292
|
+
return jsxNameText(node);
|
|
293
|
+
}
|
|
294
|
+
return getText(node);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export function getTagNameOf(node: Node): Node {
|
|
298
|
+
return getTagName(node)!;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export function getAttributesOf(node: Node): JsxAttributes {
|
|
302
|
+
return node.kind === SyntaxKind.JsxSelfClosingElement
|
|
303
|
+
? (node as JsxSelfClosingElement).attributes
|
|
304
|
+
: (node as JsxOpeningElement).attributes;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function getTypeArgumentListOf(node: Node): NodeList | undefined {
|
|
308
|
+
return getTypeArguments(node);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function getChildrenOf(node: Node): Node[] {
|
|
312
|
+
if (node.kind === SyntaxKind.JsxElement) return (node as JsxElement).children.nodes;
|
|
313
|
+
if (node.kind === SyntaxKind.JsxFragment) return (node as JsxFragment).children.nodes;
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Children that produce values: non-empty expressions, non-whitespace text and elements. */
|
|
318
|
+
export function getSemanticJsxChildren(children: readonly Node[]): Node[] {
|
|
319
|
+
const result: Node[] = [];
|
|
320
|
+
for (const child of children) {
|
|
321
|
+
if (child.kind === SyntaxKind.JsxExpression) {
|
|
322
|
+
if ((child as JsxExpression).expression !== undefined) result.push(child);
|
|
323
|
+
} else if (child.kind === SyntaxKind.JsxText) {
|
|
324
|
+
if (!(child as JsxText).containsOnlyTriviaWhiteSpaces) result.push(child);
|
|
325
|
+
} else result.push(child);
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function isHyphenatedJsxName(name: string): boolean {
|
|
331
|
+
return name.includes('-');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function getPragma(file: SourceFile, name: string, argument: string): string | undefined {
|
|
335
|
+
let result: string | undefined = undefined;
|
|
336
|
+
// The last pragma wins.
|
|
337
|
+
for (const pragma of file.pragmas) if (pragma.name === name) result = pragma.args.get(argument)?.value ?? '';
|
|
338
|
+
return result;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function isJsxTransformEnabled(c: Checker): boolean {
|
|
342
|
+
const jsx = c.compilerOptions.jsx;
|
|
343
|
+
return jsx === JsxEmit.React || jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function grammarErrorOnNode(c: Checker, node: Node, message: DiagnosticMessage, ...args: string[]): boolean {
|
|
347
|
+
if (getSourceFileOfNode(node).diagnostics.length !== 0) return false;
|
|
348
|
+
c.error(node, message, ...args);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function grammarErrorAtPos(c: Checker, node: Node, pos: number, length: number, message: DiagnosticMessage): boolean {
|
|
353
|
+
const file = getSourceFileOfNode(node);
|
|
354
|
+
if (file.diagnostics.length !== 0) return false;
|
|
355
|
+
c.addDiagnostic(new Diagnostic(file.diagnosticFile(), pos, pos + length, message, []));
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ---- The JSX namespace
|
|
360
|
+
|
|
361
|
+
/** The name of the factory namespace in scope at `location`, such as `React`. */
|
|
362
|
+
export function getJsxNamespace(c: Checker, location: Node | undefined): string {
|
|
363
|
+
if (location !== undefined) {
|
|
364
|
+
const file = getSourceFileOfNode(location);
|
|
365
|
+
const links = fileLinks(c, file);
|
|
366
|
+
if (location.kind === SyntaxKind.JsxOpeningFragment) {
|
|
367
|
+
if (links.localJsxFragmentNamespace !== '') return links.localJsxFragmentNamespace;
|
|
368
|
+
const fragmentPragma = getPragma(file, 'jsxfrag', 'factory');
|
|
369
|
+
if (fragmentPragma !== undefined) {
|
|
370
|
+
links.localJsxFragmentFactory = parseIsolatedEntityName(fragmentPragma);
|
|
371
|
+
if (links.localJsxFragmentFactory !== undefined) {
|
|
372
|
+
links.localJsxFragmentNamespace = getText(getFirstIdentifier(links.localJsxFragmentFactory));
|
|
373
|
+
return links.localJsxFragmentNamespace;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const entity = getJsxFragmentFactoryEntity(c, location);
|
|
377
|
+
if (entity !== undefined) {
|
|
378
|
+
links.localJsxFragmentFactory = entity;
|
|
379
|
+
links.localJsxFragmentNamespace = getText(getFirstIdentifier(entity));
|
|
380
|
+
return links.localJsxFragmentNamespace;
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
const local = getLocalJsxNamespace(c, file);
|
|
384
|
+
if (local !== '') {
|
|
385
|
+
links.localJsxNamespace = local;
|
|
386
|
+
return local;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const state = c.jsx;
|
|
391
|
+
if (state.jsxNamespace === '') {
|
|
392
|
+
state.jsxNamespace = 'React';
|
|
393
|
+
const factory = c.compilerOptions.jsxFactory;
|
|
394
|
+
if (factory !== undefined && factory !== '') {
|
|
395
|
+
state.jsxFactoryEntity = parseIsolatedEntityName(factory);
|
|
396
|
+
if (state.jsxFactoryEntity !== undefined)
|
|
397
|
+
state.jsxNamespace = getText(getFirstIdentifier(state.jsxFactoryEntity));
|
|
398
|
+
} else {
|
|
399
|
+
const reactNamespace = c.compilerOptions.reactNamespace;
|
|
400
|
+
if (reactNamespace !== undefined && reactNamespace !== '') state.jsxNamespace = reactNamespace;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (state.jsxFactoryEntity === undefined)
|
|
404
|
+
state.jsxFactoryEntity = parseIsolatedEntityName(state.jsxNamespace + '.createElement');
|
|
405
|
+
return state.jsxNamespace;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function getLocalJsxNamespace(c: Checker, file: SourceFile): string {
|
|
409
|
+
const links = fileLinks(c, file);
|
|
410
|
+
if (links.localJsxNamespace !== '') return links.localJsxNamespace;
|
|
411
|
+
const pragma = getPragma(file, 'jsx', 'factory');
|
|
412
|
+
if (pragma !== undefined) {
|
|
413
|
+
links.localJsxFactory = parseIsolatedEntityName(pragma);
|
|
414
|
+
if (links.localJsxFactory !== undefined) {
|
|
415
|
+
links.localJsxNamespace = getText(getFirstIdentifier(links.localJsxFactory));
|
|
416
|
+
return links.localJsxNamespace;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return '';
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function getJsxFactoryEntity(c: Checker, location: Node): Node | undefined {
|
|
423
|
+
getJsxNamespace(c, location);
|
|
424
|
+
const local = fileLinks(c, getSourceFileOfNode(location)).localJsxFactory;
|
|
425
|
+
return local ?? c.jsx.jsxFactoryEntity;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function getJsxFragmentFactoryEntity(c: Checker, location: Node): Node | undefined {
|
|
429
|
+
const file = getSourceFileOfNode(location);
|
|
430
|
+
const links = fileLinks(c, file);
|
|
431
|
+
if (links.localJsxFragmentFactory !== undefined) return links.localJsxFragmentFactory;
|
|
432
|
+
const pragma = getPragma(file, 'jsxfrag', 'factory');
|
|
433
|
+
if (pragma !== undefined) {
|
|
434
|
+
links.localJsxFragmentFactory = parseIsolatedEntityName(pragma);
|
|
435
|
+
return links.localJsxFragmentFactory;
|
|
436
|
+
}
|
|
437
|
+
const factory = c.compilerOptions.jsxFragmentFactory;
|
|
438
|
+
if (factory !== undefined && factory !== '') return parseIsolatedEntityName(factory);
|
|
439
|
+
return undefined;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** The module of the automatic runtime's implicit import, such as `react/jsx-runtime`. */
|
|
443
|
+
export function getJsxNamespaceContainerForImplicitImport(c: Checker, location: Node): Symbol | undefined {
|
|
444
|
+
const file = getSourceFileOfNode(location);
|
|
445
|
+
const links = fileLinks(c, file);
|
|
446
|
+
const cached = links.jsxImplicitImportContainer;
|
|
447
|
+
if (cached !== undefined) return cached === c.unknownSymbol ? undefined : cached;
|
|
448
|
+
const specifier = c.host.getJSXRuntimeImportSpecifier(file);
|
|
449
|
+
if (specifier === undefined) {
|
|
450
|
+
links.jsxImplicitImportContainer = c.unknownSymbol;
|
|
451
|
+
return undefined;
|
|
452
|
+
}
|
|
453
|
+
const mod = resolveExternalModule(
|
|
454
|
+
c,
|
|
455
|
+
specifier,
|
|
456
|
+
getText(specifier),
|
|
457
|
+
Diagnostics.This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_for_the_appropriate_package_installed,
|
|
458
|
+
location,
|
|
459
|
+
false,
|
|
460
|
+
);
|
|
461
|
+
const resolved = mod !== undefined && mod !== c.unknownSymbol ? resolveSymbol(c, mod) : undefined;
|
|
462
|
+
const result = resolved !== undefined ? getMergedSymbol(c, resolved) : undefined;
|
|
463
|
+
links.jsxImplicitImportContainer = result ?? c.unknownSymbol;
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/** The `JSX` namespace for `location`: the factory's, the runtime module's, or the global one. */
|
|
468
|
+
export function getJsxNamespaceAt(c: Checker, location: Node): Symbol | undefined {
|
|
469
|
+
const links = elementLinks(c, location);
|
|
470
|
+
if (links.jsxNamespace !== undefined && links.jsxNamespace !== c.unknownSymbol) return links.jsxNamespace;
|
|
471
|
+
if (links.jsxNamespace !== c.unknownSymbol) {
|
|
472
|
+
let resolvedNamespace = getJsxNamespaceContainerForImplicitImport(c, location);
|
|
473
|
+
if (resolvedNamespace === undefined || resolvedNamespace === c.unknownSymbol) {
|
|
474
|
+
const namespaceName = getJsxNamespace(c, location);
|
|
475
|
+
resolvedNamespace = resolveName(c, location, namespaceName, SymbolFlags.Namespace, undefined, false, false);
|
|
476
|
+
}
|
|
477
|
+
if (resolvedNamespace !== undefined) {
|
|
478
|
+
const container = resolveSymbol(c, resolvedNamespace)!;
|
|
479
|
+
const candidate = resolveSymbol(
|
|
480
|
+
c,
|
|
481
|
+
getSymbolOfMeaning(c, getExportsOfSymbol(c, container), jsxNamespaceName, SymbolFlags.Namespace),
|
|
482
|
+
);
|
|
483
|
+
if (candidate !== undefined && candidate !== c.unknownSymbol) {
|
|
484
|
+
links.jsxNamespace = candidate;
|
|
485
|
+
return candidate;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
links.jsxNamespace = c.unknownSymbol;
|
|
489
|
+
}
|
|
490
|
+
const global = resolveSymbol(c, getGlobalSymbol(c, jsxNamespaceName, SymbolFlags.Namespace, undefined));
|
|
491
|
+
return global === c.unknownSymbol ? undefined : global;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export function getJsxType(c: Checker, name: string, location: Node): Type {
|
|
495
|
+
const namespace = getJsxNamespaceAt(c, location);
|
|
496
|
+
if (namespace !== undefined) {
|
|
497
|
+
const typeSymbol = getSymbolOfMeaning(c, getExportsOfSymbol(c, namespace), name, SymbolFlags.Type);
|
|
498
|
+
if (typeSymbol !== undefined) return getDeclaredTypeOfSymbol(c, typeSymbol);
|
|
499
|
+
}
|
|
500
|
+
return c.errorType;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** `JSX.Element`, or the error type when it doesn't exist. */
|
|
504
|
+
export function getJsxElementTypeAt(c: Checker, location: Node): Type {
|
|
505
|
+
return getJsxType(c, jsxElementName, location);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function getJsxStatelessElementTypeAt(c: Checker, location: Node): Type | undefined {
|
|
509
|
+
return getUnionType(c, [getJsxElementTypeAt(c, location), c.nullType]);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function getJsxElementClassTypeAt(c: Checker, location: Node): Type | undefined {
|
|
513
|
+
const t = getJsxType(c, jsxElementClassName, location);
|
|
514
|
+
return isErrorType(c, t) ? undefined : t;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function getJsxElementTypeTypeAt(c: Checker, location: Node): Type | undefined {
|
|
518
|
+
const ns = getJsxNamespaceAt(c, location);
|
|
519
|
+
if (ns === undefined) return undefined;
|
|
520
|
+
const sym = getSymbolOfMeaning(c, getExportsOfSymbol(c, ns), jsxElementTypeName, SymbolFlags.Type);
|
|
521
|
+
if (sym === undefined) return undefined;
|
|
522
|
+
const t = instantiateAliasOrInterfaceWithDefaults(c, sym, []);
|
|
523
|
+
return t === undefined || isErrorType(c, t) ? undefined : t;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function instantiateAliasOrInterfaceWithDefaults(
|
|
527
|
+
c: Checker,
|
|
528
|
+
managedSym: Symbol,
|
|
529
|
+
typeArguments: Type[],
|
|
530
|
+
): Type | undefined {
|
|
531
|
+
const declaredManagedType = getDeclaredTypeOfSymbol(c, managedSym);
|
|
532
|
+
if ((managedSym.flags & SymbolFlags.TypeAlias) !== 0) {
|
|
533
|
+
const params = c.symbolLinks(managedSym).typeParameters ?? [];
|
|
534
|
+
if (params.length >= typeArguments.length) {
|
|
535
|
+
const args = fillMissingTypeArguments(c, typeArguments, params, typeArguments.length, false);
|
|
536
|
+
return args.length === 0 ? declaredManagedType : getTypeAliasInstantiation(c, managedSym, args, undefined);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if ((declaredManagedType.objectFlags & ObjectFlags.ClassOrInterface) !== 0) {
|
|
540
|
+
const params = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(c, managedSym);
|
|
541
|
+
if (params.length >= typeArguments.length) {
|
|
542
|
+
const args = fillMissingTypeArguments(c, typeArguments, params, typeArguments.length, false);
|
|
543
|
+
return createTypeReference(c, declaredManagedType, args);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* The single property name of `JSX.ElementAttributesProperty` or `JSX.ElementChildrenAttribute`: `''` when
|
|
551
|
+
* the interface is empty, `InternalSymbolName.Missing` when it doesn't exist.
|
|
552
|
+
*/
|
|
553
|
+
function getNameFromJsxElementAttributesContainer(c: Checker, containerName: string, ns: Symbol | undefined): string {
|
|
554
|
+
if (ns !== undefined) {
|
|
555
|
+
const sym = getSymbolOfMeaning(c, getExportsOfSymbol(c, ns), containerName, SymbolFlags.Type);
|
|
556
|
+
if (sym !== undefined) {
|
|
557
|
+
const props = getPropertiesOfType(c, getDeclaredTypeOfSymbol(c, sym));
|
|
558
|
+
if (props.length === 0) return '';
|
|
559
|
+
if (props.length === 1) return props[0]!.name;
|
|
560
|
+
if (declarationCount(sym) !== 0)
|
|
561
|
+
c.error(sym.declaration!, Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, containerName);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return InternalSymbolName.Missing;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
function getJsxElementPropertiesName(c: Checker, ns: Symbol | undefined): string {
|
|
568
|
+
return getNameFromJsxElementAttributesContainer(c, jsxElementAttributesPropertyName, ns);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export function getJsxElementChildrenPropertyName(c: Checker, ns: Symbol | undefined): string {
|
|
572
|
+
const jsx = c.compilerOptions.jsx;
|
|
573
|
+
// The automatic runtime always passes children as `children`.
|
|
574
|
+
if (jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev) return 'children';
|
|
575
|
+
return getNameFromJsxElementAttributesContainer(c, jsxElementChildrenAttributeName, ns);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function getJsxLibraryManagedAttributes(c: Checker, ns: Symbol | undefined): Symbol | undefined {
|
|
579
|
+
return ns !== undefined
|
|
580
|
+
? getSymbolOfMeaning(c, getExportsOfSymbol(c, ns), jsxLibraryManagedAttributesName, SymbolFlags.Type)
|
|
581
|
+
: undefined;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// ---- Intrinsic elements and props types
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* The `JSX.IntrinsicElements` property or index signature for an intrinsic tag, recording which in the
|
|
588
|
+
* element's flags; `unknownSymbol` when neither exists.
|
|
589
|
+
*/
|
|
590
|
+
export function getIntrinsicTagSymbol(c: Checker, node: Node): Symbol {
|
|
591
|
+
const links = elementLinks(c, node);
|
|
592
|
+
if (links.resolvedSymbol !== undefined) return links.resolvedSymbol;
|
|
593
|
+
const intrinsicElementsType = getJsxType(c, jsxIntrinsicElementsName, node);
|
|
594
|
+
if (!isErrorType(c, intrinsicElementsType)) {
|
|
595
|
+
const tagName = getTagNameOf(node);
|
|
596
|
+
const propName = jsxNameText(tagName);
|
|
597
|
+
const intrinsicProp = getPropertyOfType(c, intrinsicElementsType, propName);
|
|
598
|
+
if (intrinsicProp !== undefined) {
|
|
599
|
+
links.jsxFlags |= JsxFlags.IntrinsicNamedElement;
|
|
600
|
+
links.resolvedSymbol = intrinsicProp;
|
|
601
|
+
return intrinsicProp;
|
|
602
|
+
}
|
|
603
|
+
const info = getApplicableIndexInfo(c, intrinsicElementsType, getStringLiteralType(c, propName));
|
|
604
|
+
if (
|
|
605
|
+
(info !== undefined && info !== c.anyBaseTypeIndexInfo) ||
|
|
606
|
+
getApplicableIndexInfoForName(c, intrinsicElementsType, propName) !== undefined
|
|
607
|
+
) {
|
|
608
|
+
links.jsxFlags |= JsxFlags.IntrinsicIndexedElement;
|
|
609
|
+
links.resolvedSymbol = intrinsicElementsType.symbol ?? c.unknownSymbol;
|
|
610
|
+
return links.resolvedSymbol;
|
|
611
|
+
}
|
|
612
|
+
c.error(node, Diagnostics.Property_0_does_not_exist_on_type_1, propName, 'JSX.' + jsxIntrinsicElementsName);
|
|
613
|
+
links.resolvedSymbol = c.unknownSymbol;
|
|
614
|
+
return c.unknownSymbol;
|
|
615
|
+
}
|
|
616
|
+
if (c.noImplicitAny)
|
|
617
|
+
c.error(
|
|
618
|
+
node,
|
|
619
|
+
Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists,
|
|
620
|
+
jsxIntrinsicElementsName,
|
|
621
|
+
);
|
|
622
|
+
links.resolvedSymbol = c.unknownSymbol;
|
|
623
|
+
return c.unknownSymbol;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/** The props type of an intrinsic element. */
|
|
627
|
+
function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(c: Checker, node: Node): Type {
|
|
628
|
+
const links = elementLinks(c, node);
|
|
629
|
+
if (links.resolvedJsxElementAttributesType !== undefined) return links.resolvedJsxElementAttributesType;
|
|
630
|
+
const symbol = getIntrinsicTagSymbol(c, node);
|
|
631
|
+
let result: Type = c.errorType;
|
|
632
|
+
if ((links.jsxFlags & JsxFlags.IntrinsicNamedElement) !== 0) result = getTypeOfSymbol(c, symbol);
|
|
633
|
+
else if ((links.jsxFlags & JsxFlags.IntrinsicIndexedElement) !== 0) {
|
|
634
|
+
const info = getApplicableIndexInfoForName(
|
|
635
|
+
c,
|
|
636
|
+
getJsxType(c, jsxIntrinsicElementsName, node),
|
|
637
|
+
jsxNameText(getTagNameOf(node)),
|
|
638
|
+
);
|
|
639
|
+
if (info !== undefined) result = info.valueType;
|
|
640
|
+
}
|
|
641
|
+
links.resolvedJsxElementAttributesType = result;
|
|
642
|
+
return result;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
function getIntrinsicAttributesTypeFromStringLiteralType(c: Checker, t: Type, location: Node): Type | undefined {
|
|
646
|
+
const intrinsicElementsType = getJsxType(c, jsxIntrinsicElementsName, location);
|
|
647
|
+
if (isErrorType(c, intrinsicElementsType)) return c.anyType;
|
|
648
|
+
const name = (t as LiteralType).stringValue;
|
|
649
|
+
const intrinsicProp = getPropertyOfType(c, intrinsicElementsType, name);
|
|
650
|
+
if (intrinsicProp !== undefined) return getTypeOfSymbol(c, intrinsicProp);
|
|
651
|
+
return getIndexTypeOfType(c, intrinsicElementsType, c.stringType);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/** A `(props: result) => JSX.Element` signature for an intrinsic element. */
|
|
655
|
+
function createSignatureForJSXIntrinsic(c: Checker, node: Node, result: Type): Signature {
|
|
656
|
+
return newJsxIntrinsicSignature(c, result, getJsxElementTypeForIntrinsic(c, node));
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/** The return type of createSignatureForJSXIntrinsic: `JSX.Element` at `node`, or the error type. */
|
|
660
|
+
function getJsxElementTypeForIntrinsic(c: Checker, node: Node): Type {
|
|
661
|
+
let elementType: Type = c.errorType;
|
|
662
|
+
const namespace = getJsxNamespaceAt(c, node);
|
|
663
|
+
if (namespace !== undefined) {
|
|
664
|
+
const typeSymbol = getSymbolOfMeaning(c, getExportsOfSymbol(c, namespace), jsxElementName, SymbolFlags.Type);
|
|
665
|
+
if (typeSymbol !== undefined) elementType = getDeclaredTypeOfSymbol(c, typeSymbol);
|
|
666
|
+
}
|
|
667
|
+
return elementType;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
function newJsxIntrinsicSignature(c: Checker, result: Type, elementType: Type): Signature {
|
|
671
|
+
const parameterSymbol = c.newSymbol(SymbolFlags.FunctionScopedVariable, 'props');
|
|
672
|
+
c.symbolTypes.set(getSymbolId(parameterSymbol), result);
|
|
673
|
+
return c.newSignature(SignatureFlags.None, undefined, [], undefined, [parameterSymbol], elementType, 1);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* `getOrCreateTypeFromSignature(createSignatureForJSXIntrinsic(node, result))`, the type that
|
|
678
|
+
* getStaticTypeOfReferencedJsxConstructor gives an intrinsic element: `new (props: result) =>
|
|
679
|
+
* JSX.Element`. tsgo creates a new one for every element, which makes each element's
|
|
680
|
+
* `LibraryManagedAttributes<C, P>` a new instantiation; it is a function of the two types, so one is
|
|
681
|
+
* kept per pair.
|
|
682
|
+
*/
|
|
683
|
+
function getJsxIntrinsicConstructorType(c: Checker, node: Node, result: Type): Type {
|
|
684
|
+
const elementType = getJsxElementTypeForIntrinsic(c, node);
|
|
685
|
+
const key = result.id + ',' + elementType.id;
|
|
686
|
+
let t = c.jsx.intrinsicConstructorTypes.get(key);
|
|
687
|
+
if (t === undefined) {
|
|
688
|
+
t = getOrCreateTypeFromSignature(c, newJsxIntrinsicSignature(c, result, elementType));
|
|
689
|
+
c.jsx.intrinsicConstructorTypes.set(key, t);
|
|
690
|
+
}
|
|
691
|
+
return t;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function getJsxReferenceKind(c: Checker, node: Node): JsxReferenceKind {
|
|
695
|
+
const tagName = getTagNameOf(node);
|
|
696
|
+
if (isJsxIntrinsicTagName(tagName)) return JsxReferenceKind.Mixed;
|
|
697
|
+
const tagType = getApparentType(c, checkExpression(c, tagName));
|
|
698
|
+
if (getSignaturesOfType(c, tagType, SignatureKind.Construct).length !== 0) return JsxReferenceKind.Component;
|
|
699
|
+
if (getSignaturesOfType(c, tagType, SignatureKind.Call).length !== 0) return JsxReferenceKind.Function;
|
|
700
|
+
return JsxReferenceKind.Mixed;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function getUninstantiatedJsxSignaturesOfType(c: Checker, elementType: Type, caller: Node): Signature[] {
|
|
704
|
+
if ((elementType.flags & TypeFlags.String) !== 0) return [c.anySignature];
|
|
705
|
+
if ((elementType.flags & TypeFlags.StringLiteral) !== 0) {
|
|
706
|
+
const intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(c, elementType, caller);
|
|
707
|
+
if (intrinsicType === undefined) {
|
|
708
|
+
c.error(
|
|
709
|
+
caller,
|
|
710
|
+
Diagnostics.Property_0_does_not_exist_on_type_1,
|
|
711
|
+
(elementType as LiteralType).stringValue,
|
|
712
|
+
'JSX.' + jsxIntrinsicElementsName,
|
|
713
|
+
);
|
|
714
|
+
return [];
|
|
715
|
+
}
|
|
716
|
+
return [createSignatureForJSXIntrinsic(c, caller, intrinsicType)];
|
|
717
|
+
}
|
|
718
|
+
const apparentElemType = getApparentType(c, elementType);
|
|
719
|
+
// Prefer construct signatures.
|
|
720
|
+
let signatures = getSignaturesOfType(c, apparentElemType, SignatureKind.Construct);
|
|
721
|
+
if (signatures.length === 0) signatures = getSignaturesOfType(c, apparentElemType, SignatureKind.Call);
|
|
722
|
+
if (signatures.length === 0 && (apparentElemType.flags & TypeFlags.Union) !== 0) {
|
|
723
|
+
const lists: Signature[][] = [];
|
|
724
|
+
for (const t of typesOf(apparentElemType)) lists.push(getUninstantiatedJsxSignaturesOfType(c, t, caller));
|
|
725
|
+
signatures = getUnionSignatures(c, lists);
|
|
726
|
+
}
|
|
727
|
+
return signatures;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
function getTypeOfFirstParameterOfSignatureWithFallback(c: Checker, sig: Signature, fallback: Type): Type {
|
|
731
|
+
return sig.parameters.length > 0 ? getTypeAtPosition(c, sig, 0) : fallback;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/** The props type a signature expects of an element's attributes. */
|
|
735
|
+
export function getEffectiveFirstArgumentForJsxSignature(c: Checker, signature: Signature, node: Node): Type {
|
|
736
|
+
if (node.kind === SyntaxKind.JsxOpeningFragment || getJsxReferenceKind(c, node) !== JsxReferenceKind.Component)
|
|
737
|
+
return getJsxPropsTypeFromCallSignature(c, signature, node);
|
|
738
|
+
return getJsxPropsTypeFromClassType(c, signature, node);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function getJsxPropsTypeFromCallSignature(c: Checker, sig: Signature, context: Node): Type {
|
|
742
|
+
let propsType = getTypeOfFirstParameterOfSignatureWithFallback(c, sig, c.unknownType);
|
|
743
|
+
propsType = getJsxManagedAttributesFromLocatedAttributes(c, context, getJsxNamespaceAt(c, context), propsType);
|
|
744
|
+
const intrinsicAttribs = getJsxType(c, jsxIntrinsicAttributesName, context);
|
|
745
|
+
if (!isErrorType(c, intrinsicAttribs)) propsType = intersectTypes(c, intrinsicAttribs, propsType)!;
|
|
746
|
+
return propsType;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
function getJsxPropsTypeFromClassType(c: Checker, sig: Signature, context: Node): Type {
|
|
750
|
+
const ns = getJsxNamespaceAt(c, context);
|
|
751
|
+
const forcedLookupLocation = getJsxElementPropertiesName(c, ns);
|
|
752
|
+
let attributesType: Type | undefined;
|
|
753
|
+
if (forcedLookupLocation === InternalSymbolName.Missing)
|
|
754
|
+
attributesType = getTypeOfFirstParameterOfSignatureWithFallback(c, sig, c.unknownType);
|
|
755
|
+
else if (forcedLookupLocation === '') attributesType = getReturnTypeOfSignature(c, sig);
|
|
756
|
+
else {
|
|
757
|
+
attributesType = getJsxPropsTypeForSignatureFromMember(c, sig, forcedLookupLocation);
|
|
758
|
+
if (attributesType === undefined && getAttributesOf(context).properties.nodes.length !== 0)
|
|
759
|
+
c.error(
|
|
760
|
+
context,
|
|
761
|
+
Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property,
|
|
762
|
+
forcedLookupLocation,
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
if (attributesType === undefined) return c.unknownType;
|
|
766
|
+
attributesType = getJsxManagedAttributesFromLocatedAttributes(c, context, ns, attributesType);
|
|
767
|
+
if ((attributesType.flags & TypeFlags.Any) !== 0) return attributesType;
|
|
768
|
+
let apparentAttributesType = attributesType;
|
|
769
|
+
const intrinsicClassAttribs = getJsxType(c, jsxIntrinsicClassAttributesName, context);
|
|
770
|
+
if (!isErrorType(c, intrinsicClassAttribs)) {
|
|
771
|
+
const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(c, intrinsicClassAttribs.symbol!);
|
|
772
|
+
const hostClassType = getReturnTypeOfSignature(c, sig);
|
|
773
|
+
let libraryManagedAttributeType = intrinsicClassAttribs;
|
|
774
|
+
if (typeParams.length !== 0) {
|
|
775
|
+
const inferredArgs = fillMissingTypeArguments(
|
|
776
|
+
c,
|
|
777
|
+
[hostClassType],
|
|
778
|
+
typeParams,
|
|
779
|
+
getMinTypeArgumentCount(c, typeParams),
|
|
780
|
+
false,
|
|
781
|
+
);
|
|
782
|
+
libraryManagedAttributeType = instantiateType(c, intrinsicClassAttribs, newTypeMapper(typeParams, inferredArgs));
|
|
783
|
+
}
|
|
784
|
+
apparentAttributesType = intersectTypes(c, libraryManagedAttributeType, apparentAttributesType)!;
|
|
785
|
+
}
|
|
786
|
+
const intrinsicAttribs = getJsxType(c, jsxIntrinsicAttributesName, context);
|
|
787
|
+
if (!isErrorType(c, intrinsicAttribs))
|
|
788
|
+
apparentAttributesType = intersectTypes(c, intrinsicAttribs, apparentAttributesType)!;
|
|
789
|
+
return apparentAttributesType;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function getJsxPropsTypeForSignatureFromMember(c: Checker, sig: Signature, name: string): Type | undefined {
|
|
793
|
+
if (sig.composite !== undefined) {
|
|
794
|
+
// `props` of a union or intersection signature is an input: intersect the members' instance props.
|
|
795
|
+
const results: Type[] = [];
|
|
796
|
+
for (const signature of sig.composite.signatures) {
|
|
797
|
+
const instance = getReturnTypeOfSignature(c, signature);
|
|
798
|
+
if ((instance.flags & TypeFlags.Any) !== 0) return instance;
|
|
799
|
+
const propType = getTypeOfPropertyOfType(c, instance, name);
|
|
800
|
+
if (propType === undefined) return undefined;
|
|
801
|
+
results.push(propType);
|
|
802
|
+
}
|
|
803
|
+
return getIntersectionType(c, results);
|
|
804
|
+
}
|
|
805
|
+
const instanceType = getReturnTypeOfSignature(c, sig);
|
|
806
|
+
if ((instanceType.flags & TypeFlags.Any) !== 0) return instanceType;
|
|
807
|
+
return getTypeOfPropertyOfType(c, instanceType, name);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function getJsxManagedAttributesFromLocatedAttributes(
|
|
811
|
+
c: Checker,
|
|
812
|
+
context: Node,
|
|
813
|
+
ns: Symbol | undefined,
|
|
814
|
+
attributesType: Type,
|
|
815
|
+
): Type {
|
|
816
|
+
const managedSym = getJsxLibraryManagedAttributes(c, ns);
|
|
817
|
+
if (managedSym !== undefined) {
|
|
818
|
+
const ctorType = getStaticTypeOfReferencedJsxConstructor(c, context);
|
|
819
|
+
const result = instantiateAliasOrInterfaceWithDefaults(c, managedSym, [ctorType, attributesType]);
|
|
820
|
+
if (result !== undefined) return result;
|
|
821
|
+
}
|
|
822
|
+
return attributesType;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
function getStaticTypeOfReferencedJsxConstructor(c: Checker, context: Node): Type {
|
|
826
|
+
if (context.kind === SyntaxKind.JsxOpeningFragment) return getJSXFragmentType(c, context);
|
|
827
|
+
const tagName = getTagNameOf(context);
|
|
828
|
+
if (isJsxIntrinsicTagName(tagName)) {
|
|
829
|
+
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(c, context);
|
|
830
|
+
return getJsxIntrinsicConstructorType(c, context, result);
|
|
831
|
+
}
|
|
832
|
+
const tagType = checkExpressionCached(c, tagName);
|
|
833
|
+
if ((tagType.flags & TypeFlags.StringLiteral) !== 0) {
|
|
834
|
+
const result = getIntrinsicAttributesTypeFromStringLiteralType(c, tagType, context);
|
|
835
|
+
if (result === undefined) return c.errorType;
|
|
836
|
+
return getJsxIntrinsicConstructorType(c, context, result);
|
|
837
|
+
}
|
|
838
|
+
return tagType;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/** The type of the fragment factory, such as `React.Fragment`. */
|
|
842
|
+
function getJSXFragmentType(c: Checker, node: Node): Type {
|
|
843
|
+
const links = fileLinks(c, getSourceFileOfNode(node));
|
|
844
|
+
if (links.jsxFragmentType !== undefined) return links.jsxFragmentType;
|
|
845
|
+
const jsxFragmentFactoryName = getJsxNamespace(c, node);
|
|
846
|
+
// `null` is allowed as the fragment factory.
|
|
847
|
+
const shouldResolveFactoryReference =
|
|
848
|
+
(c.compilerOptions.jsx === JsxEmit.React ||
|
|
849
|
+
(c.compilerOptions.jsxFragmentFactory !== undefined && c.compilerOptions.jsxFragmentFactory !== '')) &&
|
|
850
|
+
jsxFragmentFactoryName !== 'null';
|
|
851
|
+
if (!shouldResolveFactoryReference) {
|
|
852
|
+
links.jsxFragmentType = c.anyType;
|
|
853
|
+
return c.anyType;
|
|
854
|
+
}
|
|
855
|
+
let jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(c, node);
|
|
856
|
+
if (jsxFactorySymbol === undefined) {
|
|
857
|
+
const shouldModuleRefErr =
|
|
858
|
+
c.compilerOptions.jsx !== JsxEmit.Preserve && c.compilerOptions.jsx !== JsxEmit.ReactNative;
|
|
859
|
+
let flags = SymbolFlags.Value;
|
|
860
|
+
if (!shouldModuleRefErr) flags &= ~SymbolFlags.Enum;
|
|
861
|
+
jsxFactorySymbol = resolveName(
|
|
862
|
+
c,
|
|
863
|
+
node,
|
|
864
|
+
jsxFragmentFactoryName,
|
|
865
|
+
flags,
|
|
866
|
+
Diagnostics.Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found,
|
|
867
|
+
true,
|
|
868
|
+
false,
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
if (jsxFactorySymbol === undefined) {
|
|
872
|
+
links.jsxFragmentType = c.errorType;
|
|
873
|
+
return c.errorType;
|
|
874
|
+
}
|
|
875
|
+
if (jsxFactorySymbol.name === 'Fragment') {
|
|
876
|
+
links.jsxFragmentType = getTypeOfSymbol(c, jsxFactorySymbol);
|
|
877
|
+
return links.jsxFragmentType;
|
|
878
|
+
}
|
|
879
|
+
const resolvedAlias =
|
|
880
|
+
(jsxFactorySymbol.flags & SymbolFlags.Alias) !== 0 ? resolveAlias(c, jsxFactorySymbol) : jsxFactorySymbol;
|
|
881
|
+
const typeSymbol = getSymbolOfMeaning(
|
|
882
|
+
c,
|
|
883
|
+
getExportsOfSymbol(c, resolvedAlias),
|
|
884
|
+
'Fragment',
|
|
885
|
+
SymbolFlags.BlockScopedVariable,
|
|
886
|
+
);
|
|
887
|
+
links.jsxFragmentType = typeSymbol !== undefined ? getTypeOfSymbol(c, typeSymbol) : c.errorType;
|
|
888
|
+
return links.jsxFragmentType;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// ---- Attributes and children
|
|
892
|
+
|
|
893
|
+
export function checkJsxAttribute(c: Checker, node: Node, checkMode: CheckMode): Type {
|
|
894
|
+
const initializer = (node as JsxAttribute).initializer;
|
|
895
|
+
// `<Elem attr />` is `<Elem attr={true} />`.
|
|
896
|
+
return initializer !== undefined ? checkExpressionForMutableLocationEx(c, initializer, checkMode) : c.trueType;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
export function checkJsxChildren(c: Checker, node: Node, checkMode: CheckMode): Type[] {
|
|
900
|
+
const childTypes: Type[] = [];
|
|
901
|
+
for (const child of getChildrenOf(node)) {
|
|
902
|
+
// Whitespace-only text isn't a child in React.
|
|
903
|
+
if (child.kind === SyntaxKind.JsxText) {
|
|
904
|
+
if (!(child as JsxText).containsOnlyTriviaWhiteSpaces) childTypes.push(c.stringType);
|
|
905
|
+
} else if (child.kind === SyntaxKind.JsxExpression && (child as JsxExpression).expression === undefined) continue;
|
|
906
|
+
else childTypes.push(checkExpressionForMutableLocationEx(c, child, checkMode));
|
|
907
|
+
}
|
|
908
|
+
return childTypes;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
function parentHasSemanticJsxChildren(openingLikeElement: Node): boolean {
|
|
912
|
+
const parent = openingLikeElement.parent;
|
|
913
|
+
if (parent === undefined) return false;
|
|
914
|
+
if (parent.kind === SyntaxKind.JsxElement && (parent as JsxElement).openingElement === openingLikeElement)
|
|
915
|
+
return getSemanticJsxChildren((parent as JsxElement).children.nodes).length !== 0;
|
|
916
|
+
if (parent.kind === SyntaxKind.JsxFragment && (parent as JsxFragment).openingFragment === openingLikeElement)
|
|
917
|
+
return getSemanticJsxChildren((parent as JsxFragment).children.nodes).length !== 0;
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
function createJsxAttributesType(
|
|
922
|
+
c: Checker,
|
|
923
|
+
symbol: Symbol | undefined,
|
|
924
|
+
table: SymbolTable,
|
|
925
|
+
objectFlags: ObjectFlags,
|
|
926
|
+
): Type {
|
|
927
|
+
const result = createAnonymousType(c, symbol, table, [], [], []);
|
|
928
|
+
result.objectFlags |=
|
|
929
|
+
objectFlags | ObjectFlags.FreshLiteral | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
|
|
930
|
+
return result;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/** The object type of an element's attributes and children, like an object literal's. */
|
|
934
|
+
export function createJsxAttributesTypeFromAttributesProperty(
|
|
935
|
+
c: Checker,
|
|
936
|
+
openingLikeElement: Node,
|
|
937
|
+
checkMode: CheckMode,
|
|
938
|
+
): Type {
|
|
939
|
+
const allAttributesTable: SymbolTable | undefined = c.strictNullChecks ? new Map<string, Symbol>() : undefined;
|
|
940
|
+
let attributesTable: SymbolTable = new Map<string, Symbol>();
|
|
941
|
+
let attributesSymbol: Symbol | undefined = undefined;
|
|
942
|
+
let attributeParent = openingLikeElement;
|
|
943
|
+
let spread: Type = c.emptyJsxObjectType;
|
|
944
|
+
let hasSpreadAnyType = false;
|
|
945
|
+
let typeToIntersect: Type | undefined = undefined;
|
|
946
|
+
let explicitlySpecifyChildrenAttribute = false;
|
|
947
|
+
let objectFlags = ObjectFlags.JsxAttributes;
|
|
948
|
+
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(c, getJsxNamespaceAt(c, openingLikeElement));
|
|
949
|
+
if (openingLikeElement.kind !== SyntaxKind.JsxOpeningFragment) {
|
|
950
|
+
const attributes = getAttributesOf(openingLikeElement);
|
|
951
|
+
attributesSymbol = attributes.symbol;
|
|
952
|
+
attributeParent = attributes;
|
|
953
|
+
const contextualType = getContextualType(c, attributes);
|
|
954
|
+
for (const attributeDecl of attributes.properties.nodes) {
|
|
955
|
+
if (attributeDecl.kind === SyntaxKind.JsxAttribute) {
|
|
956
|
+
const member = getSymbol(attributeDecl)!;
|
|
957
|
+
const exprType = checkJsxAttribute(c, attributeDecl, checkMode);
|
|
958
|
+
objectFlags |= exprType.objectFlags & ObjectFlags.PropagatingFlags;
|
|
959
|
+
const attributeSymbol = c.newSymbol(SymbolFlags.Property | member.flags, member.name);
|
|
960
|
+
copyDeclarations(attributeSymbol, member);
|
|
961
|
+
attributeSymbol.parent = member.parent;
|
|
962
|
+
if (member.valueDeclaration !== undefined) attributeSymbol.valueDeclaration = member.valueDeclaration;
|
|
963
|
+
const id = getSymbolId(attributeSymbol);
|
|
964
|
+
c.symbolTypes.set(id, exprType);
|
|
965
|
+
c.symbolTargets.set(id, member);
|
|
966
|
+
attributesTable.set(attributeSymbol.name, attributeSymbol);
|
|
967
|
+
if (allAttributesTable !== undefined) allAttributesTable.set(attributeSymbol.name, attributeSymbol);
|
|
968
|
+
if (jsxNameText((attributeDecl as JsxAttribute).name) === jsxChildrenPropertyName)
|
|
969
|
+
explicitlySpecifyChildrenAttribute = true;
|
|
970
|
+
if (contextualType !== undefined) checkDeprecatedJsxAttribute(c, contextualType, attributeDecl as JsxAttribute);
|
|
971
|
+
if (
|
|
972
|
+
contextualType !== undefined &&
|
|
973
|
+
(checkMode & CheckMode.Inferential) !== 0 &&
|
|
974
|
+
(checkMode & CheckMode.SkipContextSensitive) === 0 &&
|
|
975
|
+
isContextSensitive(c, attributeDecl)
|
|
976
|
+
) {
|
|
977
|
+
// Inferences flowing between context-sensitive attributes are made before fixing.
|
|
978
|
+
const inferenceContext = getInferenceContext(c, attributes);
|
|
979
|
+
const initializer = (attributeDecl as JsxAttribute).initializer;
|
|
980
|
+
if (inferenceContext !== undefined && initializer !== undefined)
|
|
981
|
+
addIntraExpressionInferenceSite(inferenceContext, getExpression(initializer)!, exprType);
|
|
982
|
+
}
|
|
983
|
+
} else {
|
|
984
|
+
if (attributesTable.size !== 0) {
|
|
985
|
+
// Attribute objects are fresh, and so are spreads after the first one.
|
|
986
|
+
objectFlags |= ObjectFlags.FreshLiteral;
|
|
987
|
+
spread = getSpreadType(
|
|
988
|
+
c,
|
|
989
|
+
spread,
|
|
990
|
+
createJsxAttributesType(c, attributesSymbol, attributesTable, objectFlags),
|
|
991
|
+
attributesSymbol,
|
|
992
|
+
objectFlags,
|
|
993
|
+
false,
|
|
994
|
+
);
|
|
995
|
+
attributesTable = new Map<string, Symbol>();
|
|
996
|
+
}
|
|
997
|
+
const expression = (attributeDecl as JsxSpreadAttribute).expression;
|
|
998
|
+
const exprType = getReducedType(c, checkExpressionEx(c, expression, checkMode & CheckMode.Inferential));
|
|
999
|
+
if ((exprType.flags & TypeFlags.Any) !== 0) hasSpreadAnyType = true;
|
|
1000
|
+
if (isValidSpreadType(c, exprType)) {
|
|
1001
|
+
spread = getSpreadType(c, spread, exprType, attributesSymbol, objectFlags, false);
|
|
1002
|
+
if (allAttributesTable !== undefined)
|
|
1003
|
+
checkSpreadPropOverrides(c, exprType, allAttributesTable, attributeDecl);
|
|
1004
|
+
} else {
|
|
1005
|
+
c.error(expression, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
|
1006
|
+
typeToIntersect =
|
|
1007
|
+
typeToIntersect !== undefined ? getIntersectionType(c, [typeToIntersect, exprType]) : exprType;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if (!hasSpreadAnyType && attributesTable.size !== 0) {
|
|
1012
|
+
objectFlags |= ObjectFlags.FreshLiteral;
|
|
1013
|
+
spread = getSpreadType(
|
|
1014
|
+
c,
|
|
1015
|
+
spread,
|
|
1016
|
+
createJsxAttributesType(c, attributesSymbol, attributesTable, objectFlags),
|
|
1017
|
+
attributesSymbol,
|
|
1018
|
+
objectFlags,
|
|
1019
|
+
false,
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (parentHasSemanticJsxChildren(openingLikeElement)) {
|
|
1024
|
+
const childTypes = checkJsxChildren(c, openingLikeElement.parent!, checkMode);
|
|
1025
|
+
if (!hasSpreadAnyType && jsxChildrenPropertyName !== InternalSymbolName.Missing && jsxChildrenPropertyName !== '') {
|
|
1026
|
+
// Children overwrite a `children` attribute; one from a spread isn't reported.
|
|
1027
|
+
if (explicitlySpecifyChildrenAttribute)
|
|
1028
|
+
c.error(
|
|
1029
|
+
attributeParent,
|
|
1030
|
+
Diagnostics.X_0_are_specified_twice_The_attribute_named_0_will_be_overwritten,
|
|
1031
|
+
jsxChildrenPropertyName,
|
|
1032
|
+
);
|
|
1033
|
+
let childrenContextualType: Type | undefined = undefined;
|
|
1034
|
+
if (openingLikeElement.kind === SyntaxKind.JsxOpeningElement) {
|
|
1035
|
+
const contextualType = getApparentTypeOfContextualType(c, getAttributesOf(openingLikeElement));
|
|
1036
|
+
if (contextualType !== undefined)
|
|
1037
|
+
childrenContextualType = getTypeOfPropertyOfContextualType(c, contextualType, jsxChildrenPropertyName);
|
|
1038
|
+
}
|
|
1039
|
+
const childrenPropSymbol = c.newSymbol(SymbolFlags.Property, jsxChildrenPropertyName);
|
|
1040
|
+
const id = getSymbolId(childrenPropSymbol);
|
|
1041
|
+
if (childTypes.length === 1) c.symbolTypes.set(id, childTypes[0]!);
|
|
1042
|
+
else if (childrenContextualType !== undefined && someType(childrenContextualType, (t) => isTupleLikeType(c, t)))
|
|
1043
|
+
c.symbolTypes.set(id, createTupleType(c, childTypes));
|
|
1044
|
+
else c.symbolTypes.set(id, createArrayType(c, getUnionType(c, childTypes)));
|
|
1045
|
+
// A property signature in the attributes declares the synthetic `children` property, so it is
|
|
1046
|
+
// checked as an excess property like the attributes.
|
|
1047
|
+
const childrenDeclaration = new PropertySignatureDeclaration(
|
|
1048
|
+
undefined,
|
|
1049
|
+
new Identifier(jsxChildrenPropertyName),
|
|
1050
|
+
undefined,
|
|
1051
|
+
undefined,
|
|
1052
|
+
undefined,
|
|
1053
|
+
);
|
|
1054
|
+
childrenDeclaration.parent = attributeParent;
|
|
1055
|
+
childrenDeclaration.symbol = childrenPropSymbol;
|
|
1056
|
+
childrenPropSymbol.valueDeclaration = childrenDeclaration;
|
|
1057
|
+
const childPropMap: SymbolTable = new Map<string, Symbol>();
|
|
1058
|
+
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
|
|
1059
|
+
spread = getSpreadType(
|
|
1060
|
+
c,
|
|
1061
|
+
spread,
|
|
1062
|
+
createAnonymousType(c, attributesSymbol, childPropMap, [], [], []),
|
|
1063
|
+
attributesSymbol,
|
|
1064
|
+
objectFlags | getPropagatingFlagsOfTypes(childTypes, TypeFlags.None),
|
|
1065
|
+
false,
|
|
1066
|
+
);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
if (hasSpreadAnyType) return c.anyType;
|
|
1070
|
+
if (typeToIntersect !== undefined)
|
|
1071
|
+
return spread !== c.emptyJsxObjectType ? getIntersectionType(c, [typeToIntersect, spread]) : typeToIntersect;
|
|
1072
|
+
if (spread === c.emptyJsxObjectType)
|
|
1073
|
+
return createJsxAttributesType(c, attributesSymbol, attributesTable, objectFlags);
|
|
1074
|
+
return spread;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
export function isTupleLikeType(c: Checker, t: Type): boolean {
|
|
1078
|
+
if (isTupleType(t) || getPropertyOfType(c, t, '0') !== undefined) return true;
|
|
1079
|
+
if (isArrayLikeType(c, t)) {
|
|
1080
|
+
const lengthType = getTypeOfPropertyOfType(c, t, 'length');
|
|
1081
|
+
if (lengthType !== undefined) return everyType(lengthType, (u) => (u.flags & TypeFlags.NumberLiteral) !== 0);
|
|
1082
|
+
}
|
|
1083
|
+
return false;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
export function isArrayOrTupleLikeType(c: Checker, t: Type): boolean {
|
|
1087
|
+
return isArrayLikeType(c, t) || isTupleLikeType(c, t);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// ---- Signature resolution
|
|
1091
|
+
|
|
1092
|
+
/** The attributes argument of an element, if it has attributes or children. */
|
|
1093
|
+
export function getEffectiveJsxArguments(node: Node): Node[] {
|
|
1094
|
+
const attributes = getAttributesOf(node);
|
|
1095
|
+
if (
|
|
1096
|
+
attributes.properties.nodes.length !== 0 ||
|
|
1097
|
+
(node.kind === SyntaxKind.JsxOpeningElement && (node.parent as JsxElement).children.nodes.length !== 0)
|
|
1098
|
+
)
|
|
1099
|
+
return [attributes];
|
|
1100
|
+
return [];
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
/** Whether `signature` accepts the element's attributes, reporting why not when `reportErrors`. */
|
|
1104
|
+
export function checkApplicableSignatureForJsxCallLikeElement(
|
|
1105
|
+
c: Checker,
|
|
1106
|
+
node: Node,
|
|
1107
|
+
signature: Signature,
|
|
1108
|
+
relation: Relation,
|
|
1109
|
+
checkMode: CheckMode,
|
|
1110
|
+
reportErrors: boolean,
|
|
1111
|
+
diagnosticOutput: Diagnostic[] | undefined,
|
|
1112
|
+
): boolean {
|
|
1113
|
+
// Function components get props, context and an updater; only props come from attributes.
|
|
1114
|
+
const paramType = getEffectiveFirstArgumentForJsxSignature(c, signature, node);
|
|
1115
|
+
const attributesType =
|
|
1116
|
+
node.kind === SyntaxKind.JsxOpeningFragment
|
|
1117
|
+
? createJsxAttributesTypeFromAttributesProperty(c, node, CheckMode.Normal)
|
|
1118
|
+
: checkExpressionWithContextualType(c, getAttributesOf(node), paramType, undefined, checkMode);
|
|
1119
|
+
const checkAttributesType =
|
|
1120
|
+
(checkMode & CheckMode.SkipContextSensitive) !== 0
|
|
1121
|
+
? getRegularTypeOfObjectLiteral(c, attributesType)
|
|
1122
|
+
: attributesType;
|
|
1123
|
+
if (!checkTagNameDoesNotExpectTooManyArguments(c, node, reportErrors, diagnosticOutput)) return false;
|
|
1124
|
+
const errorNode = reportErrors
|
|
1125
|
+
? node.kind === SyntaxKind.JsxOpeningFragment
|
|
1126
|
+
? node
|
|
1127
|
+
: getTagNameOf(node)
|
|
1128
|
+
: undefined;
|
|
1129
|
+
const attributes = node.kind === SyntaxKind.JsxOpeningFragment ? undefined : getAttributesOf(node);
|
|
1130
|
+
return checkTypeRelatedToAndOptionallyElaborate(
|
|
1131
|
+
c,
|
|
1132
|
+
checkAttributesType,
|
|
1133
|
+
paramType,
|
|
1134
|
+
relation,
|
|
1135
|
+
errorNode,
|
|
1136
|
+
attributes,
|
|
1137
|
+
undefined,
|
|
1138
|
+
diagnosticOutput,
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/** Whether a function component's required parameters fit what the factory passes it. */
|
|
1143
|
+
function checkTagNameDoesNotExpectTooManyArguments(
|
|
1144
|
+
c: Checker,
|
|
1145
|
+
node: Node,
|
|
1146
|
+
reportErrors: boolean,
|
|
1147
|
+
diagnosticOutput: Diagnostic[] | undefined,
|
|
1148
|
+
): boolean {
|
|
1149
|
+
// The automatic runtime's factories aren't looked at.
|
|
1150
|
+
if (getJsxNamespaceContainerForImplicitImport(c, node) !== undefined) return true;
|
|
1151
|
+
if (node.kind === SyntaxKind.JsxOpeningFragment) return true;
|
|
1152
|
+
const tagName = getTagNameOf(node);
|
|
1153
|
+
if (isJsxIntrinsicTagName(tagName)) return true;
|
|
1154
|
+
const tagType = checkExpression(c, tagName);
|
|
1155
|
+
const tagCallSignatures = getSignaturesOfType(c, tagType, SignatureKind.Call);
|
|
1156
|
+
if (tagCallSignatures.length === 0) return true;
|
|
1157
|
+
const factory = getJsxFactoryEntity(c, node);
|
|
1158
|
+
if (factory === undefined) return true;
|
|
1159
|
+
const factorySymbol = resolveEntityName(c, factory, SymbolFlags.Value, true, false, node);
|
|
1160
|
+
if (factorySymbol === undefined) return true;
|
|
1161
|
+
const callSignatures = getSignaturesOfType(c, getTypeOfSymbol(c, factorySymbol), SignatureKind.Call);
|
|
1162
|
+
if (callSignatures.length === 0) return true;
|
|
1163
|
+
let hasFirstParamSignatures = false;
|
|
1164
|
+
let maxParamCount = 0;
|
|
1165
|
+
// Some first parameter must expect a function component that takes the element's arguments.
|
|
1166
|
+
for (const sig of callSignatures) {
|
|
1167
|
+
const firstParam = getTypeAtPosition(c, sig, 0);
|
|
1168
|
+
for (const paramSig of getSignaturesOfType(c, firstParam, SignatureKind.Call)) {
|
|
1169
|
+
hasFirstParamSignatures = true;
|
|
1170
|
+
if (hasEffectiveRestParameter(c, paramSig)) return true;
|
|
1171
|
+
maxParamCount = Math.max(maxParamCount, getParameterCount(c, paramSig));
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
// Generic factories have no signatures to look at.
|
|
1175
|
+
if (!hasFirstParamSignatures) return true;
|
|
1176
|
+
let absoluteMinArgCount = Number.MAX_SAFE_INTEGER;
|
|
1177
|
+
for (const tagSig of tagCallSignatures)
|
|
1178
|
+
absoluteMinArgCount = Math.min(absoluteMinArgCount, getMinArgumentCount(c, tagSig));
|
|
1179
|
+
if (absoluteMinArgCount <= maxParamCount) return true;
|
|
1180
|
+
if (reportErrors) {
|
|
1181
|
+
const diagnostic = createDiagnosticForNode(
|
|
1182
|
+
tagName,
|
|
1183
|
+
Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3,
|
|
1184
|
+
[entityNameToString(tagName), String(absoluteMinArgCount), entityNameToString(factory), String(maxParamCount)],
|
|
1185
|
+
);
|
|
1186
|
+
const tagNameSymbol = getSymbolOfTagName(c, tagName);
|
|
1187
|
+
if (tagNameSymbol !== undefined && tagNameSymbol.valueDeclaration !== undefined)
|
|
1188
|
+
diagnostic.addRelatedInfo(
|
|
1189
|
+
createDiagnosticForNode(tagNameSymbol.valueDeclaration, Diagnostics.X_0_is_declared_here, [
|
|
1190
|
+
entityNameToString(tagName),
|
|
1191
|
+
]),
|
|
1192
|
+
);
|
|
1193
|
+
reportDiagnostic(c, diagnostic, diagnosticOutput);
|
|
1194
|
+
}
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
function getSymbolOfTagName(c: Checker, tagName: Node): Symbol | undefined {
|
|
1199
|
+
if (tagName.kind === SyntaxKind.Identifier || tagName.kind === SyntaxKind.PropertyAccessExpression)
|
|
1200
|
+
return resolveEntityName(c, tagName, SymbolFlags.Value, true, false, undefined);
|
|
1201
|
+
return undefined;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
function reportDiagnostic(c: Checker, diagnostic: Diagnostic, output: Diagnostic[] | undefined): void {
|
|
1205
|
+
if (output !== undefined) output.push(diagnostic);
|
|
1206
|
+
else c.addDiagnostic(diagnostic);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
export function resolveJsxOpeningLikeElement(c: Checker, node: Node, checkMode: CheckMode): Signature {
|
|
1210
|
+
const isJsxOpenFragment = node.kind === SyntaxKind.JsxOpeningFragment;
|
|
1211
|
+
let exprTypes: Type;
|
|
1212
|
+
if (!isJsxOpenFragment) {
|
|
1213
|
+
const tagName = getTagNameOf(node);
|
|
1214
|
+
if (isJsxIntrinsicTagName(tagName)) {
|
|
1215
|
+
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(c, node);
|
|
1216
|
+
const fakeSignature = createSignatureForJSXIntrinsic(c, node, result);
|
|
1217
|
+
const attributes = getAttributesOf(node);
|
|
1218
|
+
checkTypeAssignableToAndOptionallyElaborateJsx(
|
|
1219
|
+
c,
|
|
1220
|
+
checkExpressionWithContextualType(
|
|
1221
|
+
c,
|
|
1222
|
+
attributes,
|
|
1223
|
+
getEffectiveFirstArgumentForJsxSignature(c, fakeSignature, node),
|
|
1224
|
+
undefined,
|
|
1225
|
+
CheckMode.Normal,
|
|
1226
|
+
),
|
|
1227
|
+
result,
|
|
1228
|
+
tagName,
|
|
1229
|
+
attributes,
|
|
1230
|
+
);
|
|
1231
|
+
const typeArguments = getTypeArgumentListOf(node);
|
|
1232
|
+
if (typeArguments !== undefined && typeArguments.nodes.length !== 0) {
|
|
1233
|
+
for (const t of typeArguments.nodes) checkSourceElement(c, t);
|
|
1234
|
+
const file = getSourceFileOfNode(node);
|
|
1235
|
+
c.addDiagnostic(
|
|
1236
|
+
new Diagnostic(
|
|
1237
|
+
file.diagnosticFile(),
|
|
1238
|
+
skipTrivia(file.text, typeArguments.pos),
|
|
1239
|
+
typeArguments.end,
|
|
1240
|
+
Diagnostics.Expected_0_type_arguments_but_got_1,
|
|
1241
|
+
['0', String(typeArguments.nodes.length)],
|
|
1242
|
+
),
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
return fakeSignature;
|
|
1246
|
+
}
|
|
1247
|
+
exprTypes = checkExpression(c, tagName);
|
|
1248
|
+
} else exprTypes = getJSXFragmentType(c, node);
|
|
1249
|
+
const apparentType = getApparentType(c, exprTypes);
|
|
1250
|
+
if (isErrorType(c, apparentType)) return resolveErrorCall(c, node);
|
|
1251
|
+
const signatures = getUninstantiatedJsxSignaturesOfType(c, exprTypes, node);
|
|
1252
|
+
if (isUntypedFunctionCall(c, exprTypes, apparentType, signatures.length)) return resolveUntypedCall(c, node);
|
|
1253
|
+
if (signatures.length === 0) {
|
|
1254
|
+
const errorNode = isJsxOpenFragment ? node : getTagNameOf(node);
|
|
1255
|
+
c.error(
|
|
1256
|
+
errorNode,
|
|
1257
|
+
Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures,
|
|
1258
|
+
getTextOfNode(errorNode),
|
|
1259
|
+
);
|
|
1260
|
+
return resolveErrorCall(c, node);
|
|
1261
|
+
}
|
|
1262
|
+
return resolveCall(c, node, signatures, checkMode, SignatureFlags.None, undefined);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
function checkTypeAssignableToAndOptionallyElaborateJsx(
|
|
1266
|
+
c: Checker,
|
|
1267
|
+
source: Type,
|
|
1268
|
+
target: Type,
|
|
1269
|
+
errorNode: Node,
|
|
1270
|
+
expr: Node,
|
|
1271
|
+
): boolean {
|
|
1272
|
+
return checkTypeRelatedToAndOptionallyElaborate(
|
|
1273
|
+
c,
|
|
1274
|
+
source,
|
|
1275
|
+
target,
|
|
1276
|
+
c.assignableRelation,
|
|
1277
|
+
errorNode,
|
|
1278
|
+
expr,
|
|
1279
|
+
undefined,
|
|
1280
|
+
undefined,
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
function isUntypedFunctionCall(c: Checker, funcType: Type, apparentFuncType: Type, numCallSignatures: number): boolean {
|
|
1285
|
+
if ((funcType.flags & TypeFlags.Any) !== 0) return true;
|
|
1286
|
+
if ((apparentFuncType.flags & TypeFlags.Any) !== 0) return true;
|
|
1287
|
+
if ((funcType.flags & TypeFlags.TypeParameter) !== 0) return false;
|
|
1288
|
+
return (
|
|
1289
|
+
numCallSignatures === 0 &&
|
|
1290
|
+
(apparentFuncType.flags & TypeFlags.Union) === 0 &&
|
|
1291
|
+
(getReducedType(c, apparentFuncType).flags & TypeFlags.Never) === 0 &&
|
|
1292
|
+
isTypeAssignableTo(c, funcType, c.globalFunctionType)
|
|
1293
|
+
);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
function resolveUntypedCall(c: Checker, node: Node): Signature {
|
|
1297
|
+
if (node.kind !== SyntaxKind.JsxOpeningFragment) {
|
|
1298
|
+
// Type arguments are checked even though an untyped element can't accept them: they get their
|
|
1299
|
+
// diagnostics and mark what they reference as used.
|
|
1300
|
+
const typeArguments = getTypeArgumentListOf(node);
|
|
1301
|
+
if (typeArguments !== undefined) for (const t of typeArguments.nodes) checkSourceElement(c, t);
|
|
1302
|
+
checkExpression(c, getAttributesOf(node));
|
|
1303
|
+
}
|
|
1304
|
+
return c.anySignature;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
function resolveErrorCall(c: Checker, node: Node): Signature {
|
|
1308
|
+
resolveUntypedCall(c, node);
|
|
1309
|
+
return c.unknownSignature;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
/** The signature an element resolves to, computed once. */
|
|
1313
|
+
export function getResolvedJsxSignature(c: Checker, node: Node): Signature {
|
|
1314
|
+
return getResolvedSignature(c, node, CheckMode.Normal);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
/** Infers a generic component's type arguments from the element's attributes. */
|
|
1318
|
+
export function inferJsxTypeArguments(
|
|
1319
|
+
c: Checker,
|
|
1320
|
+
node: Node,
|
|
1321
|
+
signature: Signature,
|
|
1322
|
+
checkMode: CheckMode,
|
|
1323
|
+
context: InferenceContext,
|
|
1324
|
+
): Type[] {
|
|
1325
|
+
const paramType = getEffectiveFirstArgumentForJsxSignature(c, signature, node);
|
|
1326
|
+
const checkAttrType = checkExpressionWithContextualType(c, getAttributesOf(node), paramType, context, checkMode);
|
|
1327
|
+
inferTypes(c, context.inferences, checkAttrType, paramType, InferencePriority.None, false);
|
|
1328
|
+
return getInferredTypes(c, context);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// ---- Checking
|
|
1332
|
+
|
|
1333
|
+
/** Checks a JSX expression, element, fragment or attributes node. */
|
|
1334
|
+
export function checkJsx(c: Checker, node: Node, checkMode: CheckMode): Type {
|
|
1335
|
+
switch (node.kind) {
|
|
1336
|
+
case SyntaxKind.JsxExpression:
|
|
1337
|
+
return checkJsxExpression(c, node as JsxExpression, checkMode);
|
|
1338
|
+
case SyntaxKind.JsxElement:
|
|
1339
|
+
case SyntaxKind.JsxSelfClosingElement: {
|
|
1340
|
+
checkNodeDeferred(c, node);
|
|
1341
|
+
return getJsxElementTypeAt(c, node);
|
|
1342
|
+
}
|
|
1343
|
+
case SyntaxKind.JsxFragment:
|
|
1344
|
+
return checkJsxFragment(c, node as JsxFragment);
|
|
1345
|
+
case SyntaxKind.JsxAttributes:
|
|
1346
|
+
return createJsxAttributesTypeFromAttributesProperty(c, node.parent!, checkMode);
|
|
1347
|
+
}
|
|
1348
|
+
return c.errorType;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
function checkJsxExpression(c: Checker, node: JsxExpression, checkMode: CheckMode): Type {
|
|
1352
|
+
checkGrammarJsxExpression(c, node);
|
|
1353
|
+
if (node.expression === undefined) return c.errorType;
|
|
1354
|
+
const t = checkExpressionEx(c, node.expression, checkMode);
|
|
1355
|
+
if (node.dotDotDotToken !== undefined && t !== c.anyType && !isArrayType(c, t))
|
|
1356
|
+
c.error(node, Diagnostics.JSX_spread_child_must_be_an_array_type);
|
|
1357
|
+
return t;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
function checkJsxFragment(c: Checker, node: JsxFragment): Type {
|
|
1361
|
+
checkJsxOpeningLikeElementOrOpeningFragment(c, node.openingFragment);
|
|
1362
|
+
// With a custom factory, fragments need a fragment factory too.
|
|
1363
|
+
const file = getSourceFileOfNode(node);
|
|
1364
|
+
const options = c.compilerOptions;
|
|
1365
|
+
const hasFactory = options.jsxFactory !== undefined && options.jsxFactory !== '';
|
|
1366
|
+
const hasFragmentFactory = options.jsxFragmentFactory !== undefined && options.jsxFragmentFactory !== '';
|
|
1367
|
+
if (
|
|
1368
|
+
isJsxTransformEnabled(c) &&
|
|
1369
|
+
(hasFactory || getPragma(file, 'jsx', 'factory') !== undefined) &&
|
|
1370
|
+
!hasFragmentFactory &&
|
|
1371
|
+
getPragma(file, 'jsxfrag', 'factory') === undefined
|
|
1372
|
+
)
|
|
1373
|
+
c.error(
|
|
1374
|
+
node,
|
|
1375
|
+
hasFactory
|
|
1376
|
+
? Diagnostics.The_jsxFragmentFactory_compiler_option_must_be_provided_to_use_JSX_fragments_with_the_jsxFactory_compiler_option
|
|
1377
|
+
: Diagnostics.An_jsxFrag_pragma_is_required_when_using_an_jsx_pragma_with_JSX_fragments,
|
|
1378
|
+
);
|
|
1379
|
+
checkJsxChildren(c, node, CheckMode.Normal);
|
|
1380
|
+
const t = getJsxElementTypeAt(c, node);
|
|
1381
|
+
return isErrorType(c, t) ? c.anyType : t;
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
/** The deferred check of an element: its signature, closing tag and children. */
|
|
1385
|
+
export function checkJsxElementDeferred(c: Checker, node: Node): void {
|
|
1386
|
+
if (node.kind === SyntaxKind.JsxSelfClosingElement) {
|
|
1387
|
+
checkJsxOpeningLikeElementOrOpeningFragment(c, node);
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
const element = node as JsxElement;
|
|
1391
|
+
checkJsxOpeningLikeElementOrOpeningFragment(c, element.openingElement);
|
|
1392
|
+
const closingTagName = element.closingElement.tagName;
|
|
1393
|
+
if (isJsxIntrinsicTagName(closingTagName)) getIntrinsicTagSymbol(c, element.closingElement);
|
|
1394
|
+
else checkExpression(c, closingTagName);
|
|
1395
|
+
checkJsxChildren(c, node, CheckMode.Normal);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
function checkJsxOpeningLikeElementOrOpeningFragment(c: Checker, node: Node): void {
|
|
1399
|
+
const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node);
|
|
1400
|
+
if (isNodeOpeningLikeElement) checkGrammarJsxElement(c, node);
|
|
1401
|
+
checkJsxPreconditions(c, node);
|
|
1402
|
+
markJsxAliasReferenced(c, node);
|
|
1403
|
+
const sig = getResolvedJsxSignature(c, node);
|
|
1404
|
+
checkDeprecatedSignature(c, sig, node);
|
|
1405
|
+
if (!isNodeOpeningLikeElement) return;
|
|
1406
|
+
const elementTypeConstraint = getJsxElementTypeTypeAt(c, node);
|
|
1407
|
+
if (elementTypeConstraint !== undefined) {
|
|
1408
|
+
const tagName = getTagNameOf(node);
|
|
1409
|
+
const tagType = isJsxIntrinsicTagName(tagName)
|
|
1410
|
+
? getStringLiteralType(c, jsxNameText(tagName))
|
|
1411
|
+
: checkExpression(c, tagName);
|
|
1412
|
+
const diagnostics: Diagnostic[] = [];
|
|
1413
|
+
if (
|
|
1414
|
+
!checkTypeRelatedTo(
|
|
1415
|
+
c,
|
|
1416
|
+
tagType,
|
|
1417
|
+
elementTypeConstraint,
|
|
1418
|
+
c.assignableRelation,
|
|
1419
|
+
tagName,
|
|
1420
|
+
Diagnostics.Its_type_0_is_not_a_valid_JSX_element_type,
|
|
1421
|
+
diagnostics,
|
|
1422
|
+
)
|
|
1423
|
+
)
|
|
1424
|
+
c.addDiagnostic(
|
|
1425
|
+
chainDiagnostic(diagnostics[0]!, Diagnostics.X_0_cannot_be_used_as_a_JSX_component, getTextOfNode(tagName)),
|
|
1426
|
+
);
|
|
1427
|
+
} else
|
|
1428
|
+
checkJsxReturnAssignableToAppropriateBound(c, getJsxReferenceKind(c, node), getReturnTypeOfSignature(c, sig), node);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
function checkJsxPreconditions(c: Checker, errorNode: Node): void {
|
|
1432
|
+
if (c.compilerOptions.jsx === undefined)
|
|
1433
|
+
c.error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
|
|
1434
|
+
// A missing `JSX.Element` is the error type rather than absent, so TS2602 is never reported.
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
function checkJsxReturnAssignableToAppropriateBound(
|
|
1438
|
+
c: Checker,
|
|
1439
|
+
refKind: JsxReferenceKind,
|
|
1440
|
+
elemInstanceType: Type,
|
|
1441
|
+
openingLikeElement: Node,
|
|
1442
|
+
): void {
|
|
1443
|
+
const diagnostics: Diagnostic[] = [];
|
|
1444
|
+
const tagName = getTagNameOf(openingLikeElement);
|
|
1445
|
+
if (refKind === JsxReferenceKind.Function) {
|
|
1446
|
+
const sfcReturnConstraint = getJsxStatelessElementTypeAt(c, openingLikeElement);
|
|
1447
|
+
if (sfcReturnConstraint !== undefined)
|
|
1448
|
+
checkTypeRelatedTo(
|
|
1449
|
+
c,
|
|
1450
|
+
elemInstanceType,
|
|
1451
|
+
sfcReturnConstraint,
|
|
1452
|
+
c.assignableRelation,
|
|
1453
|
+
tagName,
|
|
1454
|
+
Diagnostics.Its_return_type_0_is_not_a_valid_JSX_element,
|
|
1455
|
+
diagnostics,
|
|
1456
|
+
);
|
|
1457
|
+
} else if (refKind === JsxReferenceKind.Component) {
|
|
1458
|
+
const classConstraint = getJsxElementClassTypeAt(c, openingLikeElement);
|
|
1459
|
+
if (classConstraint !== undefined)
|
|
1460
|
+
checkTypeRelatedTo(
|
|
1461
|
+
c,
|
|
1462
|
+
elemInstanceType,
|
|
1463
|
+
classConstraint,
|
|
1464
|
+
c.assignableRelation,
|
|
1465
|
+
tagName,
|
|
1466
|
+
Diagnostics.Its_instance_type_0_is_not_a_valid_JSX_element,
|
|
1467
|
+
diagnostics,
|
|
1468
|
+
);
|
|
1469
|
+
} else {
|
|
1470
|
+
const sfcReturnConstraint = getJsxStatelessElementTypeAt(c, openingLikeElement);
|
|
1471
|
+
const classConstraint = getJsxElementClassTypeAt(c, openingLikeElement);
|
|
1472
|
+
if (sfcReturnConstraint === undefined || classConstraint === undefined) return;
|
|
1473
|
+
const combined = getUnionType(c, [sfcReturnConstraint, classConstraint]);
|
|
1474
|
+
checkTypeRelatedTo(
|
|
1475
|
+
c,
|
|
1476
|
+
elemInstanceType,
|
|
1477
|
+
combined,
|
|
1478
|
+
c.assignableRelation,
|
|
1479
|
+
tagName,
|
|
1480
|
+
Diagnostics.Its_element_type_0_is_not_a_valid_JSX_element,
|
|
1481
|
+
diagnostics,
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
if (diagnostics.length !== 0)
|
|
1485
|
+
c.addDiagnostic(
|
|
1486
|
+
chainDiagnostic(diagnostics[0]!, Diagnostics.X_0_cannot_be_used_as_a_JSX_component, getTextOfNode(tagName)),
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/** Resolves the factory namespace, which must be in scope for the classic React transform. */
|
|
1491
|
+
function markJsxAliasReferenced(c: Checker, node: Node): void {
|
|
1492
|
+
if (getJsxNamespaceContainerForImplicitImport(c, node) !== undefined) return;
|
|
1493
|
+
const jsxFactoryRefErr =
|
|
1494
|
+
c.compilerOptions.jsx === JsxEmit.React
|
|
1495
|
+
? Diagnostics.This_JSX_tag_requires_0_to_be_in_scope_but_it_could_not_be_found
|
|
1496
|
+
: undefined;
|
|
1497
|
+
const jsxFactoryNamespace = getJsxNamespace(c, node);
|
|
1498
|
+
const jsxFactoryLocation = isJsxOpeningLikeElement(node) ? getTagNameOf(node) : node;
|
|
1499
|
+
const shouldFactoryRefErr =
|
|
1500
|
+
c.compilerOptions.jsx !== JsxEmit.Preserve && c.compilerOptions.jsx !== JsxEmit.ReactNative;
|
|
1501
|
+
let flags = SymbolFlags.Value;
|
|
1502
|
+
if (!shouldFactoryRefErr) flags &= ~SymbolFlags.Enum;
|
|
1503
|
+
// `null` is allowed as the fragment factory.
|
|
1504
|
+
if (!(node.kind === SyntaxKind.JsxOpeningFragment && jsxFactoryNamespace === 'null'))
|
|
1505
|
+
resolveName(c, jsxFactoryLocation, jsxFactoryNamespace, flags, jsxFactoryRefErr, true, false);
|
|
1506
|
+
if (node.kind === SyntaxKind.JsxOpeningFragment) {
|
|
1507
|
+
const file = getSourceFileOfNode(node);
|
|
1508
|
+
const entity = getJsxFactoryEntity(c, file);
|
|
1509
|
+
if (entity !== undefined)
|
|
1510
|
+
resolveName(c, jsxFactoryLocation, getText(getFirstIdentifier(entity)), flags, jsxFactoryRefErr, true, false);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
// ---- Grammar
|
|
1515
|
+
|
|
1516
|
+
function checkGrammarJsxElement(c: Checker, node: Node): boolean {
|
|
1517
|
+
checkGrammarJsxName(c, getTagNameOf(node));
|
|
1518
|
+
checkGrammarTypeArguments(c, node, getTypeArgumentListOf(node));
|
|
1519
|
+
const seen = new Set<string>();
|
|
1520
|
+
for (const attrNode of getAttributesOf(node).properties.nodes) {
|
|
1521
|
+
if (attrNode.kind === SyntaxKind.JsxSpreadAttribute) continue;
|
|
1522
|
+
const attr = attrNode as JsxAttribute;
|
|
1523
|
+
const textOfName = jsxNameText(attr.name);
|
|
1524
|
+
if (seen.has(textOfName))
|
|
1525
|
+
return grammarErrorOnNode(
|
|
1526
|
+
c,
|
|
1527
|
+
attr.name,
|
|
1528
|
+
Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name,
|
|
1529
|
+
);
|
|
1530
|
+
seen.add(textOfName);
|
|
1531
|
+
const initializer = attr.initializer;
|
|
1532
|
+
if (
|
|
1533
|
+
initializer !== undefined &&
|
|
1534
|
+
initializer.kind === SyntaxKind.JsxExpression &&
|
|
1535
|
+
(initializer as JsxExpression).expression === undefined
|
|
1536
|
+
)
|
|
1537
|
+
return grammarErrorOnNode(
|
|
1538
|
+
c,
|
|
1539
|
+
initializer,
|
|
1540
|
+
Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression,
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
return false;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
function checkGrammarJsxName(c: Checker, node: Node): boolean {
|
|
1547
|
+
if (
|
|
1548
|
+
node.kind === SyntaxKind.PropertyAccessExpression &&
|
|
1549
|
+
(node as PropertyAccessExpression).expression.kind === SyntaxKind.JsxNamespacedName
|
|
1550
|
+
)
|
|
1551
|
+
return grammarErrorOnNode(
|
|
1552
|
+
c,
|
|
1553
|
+
(node as PropertyAccessExpression).expression,
|
|
1554
|
+
Diagnostics.JSX_property_access_expressions_cannot_include_JSX_namespace_names,
|
|
1555
|
+
);
|
|
1556
|
+
if (
|
|
1557
|
+
node.kind === SyntaxKind.JsxNamespacedName &&
|
|
1558
|
+
isJsxTransformEnabled(c) &&
|
|
1559
|
+
!isIntrinsicJsxName((node as JsxNamespacedName).namespace.text)
|
|
1560
|
+
)
|
|
1561
|
+
return grammarErrorOnNode(c, node, Diagnostics.React_components_cannot_include_JSX_namespace_names);
|
|
1562
|
+
return false;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
function checkGrammarTypeArguments(c: Checker, node: Node, typeArguments: NodeList | undefined): boolean {
|
|
1566
|
+
if (typeArguments === undefined) return false;
|
|
1567
|
+
if (typeArguments.hasTrailingComma())
|
|
1568
|
+
return grammarErrorAtPos(
|
|
1569
|
+
c,
|
|
1570
|
+
typeArguments.nodes[0]!,
|
|
1571
|
+
typeArguments.end - 1,
|
|
1572
|
+
1,
|
|
1573
|
+
Diagnostics.Trailing_comma_not_allowed,
|
|
1574
|
+
);
|
|
1575
|
+
if (typeArguments.nodes.length === 0) {
|
|
1576
|
+
const file = getSourceFileOfNode(node);
|
|
1577
|
+
const start = typeArguments.pos - 1;
|
|
1578
|
+
const end = skipTrivia(file.text, typeArguments.end) + 1;
|
|
1579
|
+
return grammarErrorAtPos(c, file, start, end - start, Diagnostics.Type_argument_list_cannot_be_empty);
|
|
1580
|
+
}
|
|
1581
|
+
return false;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function checkGrammarJsxExpression(c: Checker, node: JsxExpression): boolean {
|
|
1585
|
+
const expression = node.expression;
|
|
1586
|
+
if (
|
|
1587
|
+
expression !== undefined &&
|
|
1588
|
+
expression.kind === SyntaxKind.BinaryExpression &&
|
|
1589
|
+
(expression as BinaryExpression).operatorToken.kind === SyntaxKind.CommaToken
|
|
1590
|
+
)
|
|
1591
|
+
return grammarErrorOnNode(
|
|
1592
|
+
c,
|
|
1593
|
+
expression,
|
|
1594
|
+
Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array,
|
|
1595
|
+
);
|
|
1596
|
+
return false;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
// ---- Contextual types
|
|
1600
|
+
|
|
1601
|
+
export function getContextualTypeForJsxExpression(
|
|
1602
|
+
c: Checker,
|
|
1603
|
+
node: Node,
|
|
1604
|
+
contextFlags: ContextFlags,
|
|
1605
|
+
): Type | undefined {
|
|
1606
|
+
const parent = node.parent!;
|
|
1607
|
+
if (parent.kind === SyntaxKind.JsxAttribute || parent.kind === SyntaxKind.JsxSpreadAttribute)
|
|
1608
|
+
return getContextualTypeEx(c, node, contextFlags);
|
|
1609
|
+
if (parent.kind === SyntaxKind.JsxElement)
|
|
1610
|
+
return getContextualTypeForChildJsxExpression(c, parent, node, contextFlags);
|
|
1611
|
+
return undefined;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
export function getContextualTypeForJsxAttribute(
|
|
1615
|
+
c: Checker,
|
|
1616
|
+
attribute: Node,
|
|
1617
|
+
contextFlags: ContextFlags,
|
|
1618
|
+
): Type | undefined {
|
|
1619
|
+
// While a function component's signature is tried, its attributes carry the parameter type.
|
|
1620
|
+
if (attribute.kind === SyntaxKind.JsxAttribute) {
|
|
1621
|
+
const attributesType = getApparentTypeOfContextualTypeEx(c, attribute.parent!, contextFlags);
|
|
1622
|
+
if (attributesType === undefined || (attributesType.flags & TypeFlags.Any) !== 0) return undefined;
|
|
1623
|
+
return getTypeOfPropertyOfContextualType(c, attributesType, jsxNameText((attribute as JsxAttribute).name));
|
|
1624
|
+
}
|
|
1625
|
+
return getContextualTypeEx(c, attribute.parent!, contextFlags);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
export function getContextualJsxElementAttributesType(
|
|
1629
|
+
c: Checker,
|
|
1630
|
+
node: Node,
|
|
1631
|
+
contextFlags: ContextFlags,
|
|
1632
|
+
): Type | undefined {
|
|
1633
|
+
if (node.kind === SyntaxKind.JsxOpeningElement) {
|
|
1634
|
+
// Contextual types of an element's attributes are pushed onto the element, which spans the children.
|
|
1635
|
+
// Cached contextual types were obtained without flags.
|
|
1636
|
+
const index = findContextualNode(c, node.parent!, contextFlags === ContextFlags.None);
|
|
1637
|
+
if (index >= 0) return c.inferenceCaches.contextualTypes[index];
|
|
1638
|
+
}
|
|
1639
|
+
const signature =
|
|
1640
|
+
c.resolvedSignatures.get(node.id) === c.resolvingSignature
|
|
1641
|
+
? c.resolvingSignature
|
|
1642
|
+
: getResolvedJsxSignature(c, node);
|
|
1643
|
+
return getEffectiveFirstArgumentForJsxSignature(c, signature, node);
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
function getContextualTypeForChildJsxExpression(
|
|
1647
|
+
c: Checker,
|
|
1648
|
+
node: Node,
|
|
1649
|
+
child: Node,
|
|
1650
|
+
contextFlags: ContextFlags,
|
|
1651
|
+
): Type | undefined {
|
|
1652
|
+
const element = node as JsxElement;
|
|
1653
|
+
const attributesType = getApparentTypeOfContextualTypeEx(c, element.openingElement.attributes, contextFlags);
|
|
1654
|
+
// Children are the `children` attribute (named by `JSX.ElementChildrenAttribute`).
|
|
1655
|
+
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(c, getJsxNamespaceAt(c, node));
|
|
1656
|
+
if (
|
|
1657
|
+
attributesType === undefined ||
|
|
1658
|
+
(attributesType.flags & TypeFlags.Any) !== 0 ||
|
|
1659
|
+
jsxChildrenPropertyName === InternalSymbolName.Missing ||
|
|
1660
|
+
jsxChildrenPropertyName === ''
|
|
1661
|
+
)
|
|
1662
|
+
return undefined;
|
|
1663
|
+
const realChildren = getSemanticJsxChildren(element.children.nodes);
|
|
1664
|
+
const childIndex = realChildren.indexOf(child);
|
|
1665
|
+
const childFieldType = getTypeOfPropertyOfContextualType(c, attributesType, jsxChildrenPropertyName);
|
|
1666
|
+
if (childFieldType === undefined) return undefined;
|
|
1667
|
+
if (realChildren.length === 1) return childFieldType;
|
|
1668
|
+
return mapTypeEx(
|
|
1669
|
+
c,
|
|
1670
|
+
childFieldType,
|
|
1671
|
+
(t) => (isArrayLikeType(c, t) ? getIndexedAccessType(c, t, getNumberLiteralType(c, childIndex)) : t),
|
|
1672
|
+
true,
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
export function isJsxAttributesContextSensitive(c: Checker, node: Node): boolean {
|
|
1677
|
+
for (const p of (node as JsxAttributes).properties.nodes) if (isContextSensitive(c, p)) return true;
|
|
1678
|
+
if (node.parent!.kind === SyntaxKind.JsxOpeningElement)
|
|
1679
|
+
for (const child of (node.parent!.parent as JsxElement).children.nodes)
|
|
1680
|
+
if (isContextSensitive(c, child)) return true;
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
// ---- Elaboration
|
|
1685
|
+
|
|
1686
|
+
/** A child of an element that an error can be reported on. */
|
|
1687
|
+
class JsxElaborationElement {
|
|
1688
|
+
constructor(
|
|
1689
|
+
readonly errorNode: Node,
|
|
1690
|
+
readonly innerExpression: Node | undefined,
|
|
1691
|
+
readonly nameType: Type,
|
|
1692
|
+
/** Text children report this message instead of a relation error. */
|
|
1693
|
+
readonly isText: boolean,
|
|
1694
|
+
) {}
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
function getElaborationElementForJsxChild(child: Node, nameType: Type): JsxElaborationElement | undefined {
|
|
1698
|
+
switch (child.kind) {
|
|
1699
|
+
case SyntaxKind.JsxExpression:
|
|
1700
|
+
return new JsxElaborationElement(child, (child as JsxExpression).expression, nameType, false);
|
|
1701
|
+
case SyntaxKind.JsxText:
|
|
1702
|
+
// Whitespace-only text isn't a child.
|
|
1703
|
+
if ((child as JsxText).containsOnlyTriviaWhiteSpaces) return undefined;
|
|
1704
|
+
return new JsxElaborationElement(child, undefined, nameType, true);
|
|
1705
|
+
}
|
|
1706
|
+
return new JsxElaborationElement(child, child, nameType, false);
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
/** Reports attribute and children errors at the attributes and children themselves. */
|
|
1710
|
+
export function elaborateJsxComponents(
|
|
1711
|
+
c: Checker,
|
|
1712
|
+
node: Node,
|
|
1713
|
+
source: Type,
|
|
1714
|
+
target: Type,
|
|
1715
|
+
relation: Relation,
|
|
1716
|
+
diagnosticOutput: Diagnostic[] | undefined,
|
|
1717
|
+
): boolean {
|
|
1718
|
+
let reportedError = false;
|
|
1719
|
+
for (const prop of (node as JsxAttributes).properties.nodes) {
|
|
1720
|
+
if (prop.kind === SyntaxKind.JsxSpreadAttribute) continue;
|
|
1721
|
+
const attr = prop as JsxAttribute;
|
|
1722
|
+
const name = jsxNameText(attr.name);
|
|
1723
|
+
if (isHyphenatedJsxName(name)) continue;
|
|
1724
|
+
const nameType = getStringLiteralType(c, name);
|
|
1725
|
+
reportedError =
|
|
1726
|
+
elaborateElement(
|
|
1727
|
+
c,
|
|
1728
|
+
source,
|
|
1729
|
+
target,
|
|
1730
|
+
relation,
|
|
1731
|
+
attr.name,
|
|
1732
|
+
attr.initializer,
|
|
1733
|
+
nameType,
|
|
1734
|
+
undefined,
|
|
1735
|
+
undefined,
|
|
1736
|
+
[],
|
|
1737
|
+
diagnosticOutput,
|
|
1738
|
+
) || reportedError;
|
|
1739
|
+
}
|
|
1740
|
+
const opening = node.parent!;
|
|
1741
|
+
if (opening.kind !== SyntaxKind.JsxOpeningElement || opening.parent!.kind !== SyntaxKind.JsxElement)
|
|
1742
|
+
return reportedError;
|
|
1743
|
+
const containingElement = opening.parent as JsxElement;
|
|
1744
|
+
let childrenPropName = getJsxElementChildrenPropertyName(c, getJsxNamespaceAt(c, node));
|
|
1745
|
+
if (childrenPropName === InternalSymbolName.Missing) childrenPropName = 'children';
|
|
1746
|
+
const childrenNameType = getStringLiteralType(c, childrenPropName);
|
|
1747
|
+
const childrenTargetType = getIndexedAccessType(c, target, childrenNameType);
|
|
1748
|
+
const validChildren = getSemanticJsxChildren(containingElement.children.nodes);
|
|
1749
|
+
if (validChildren.length === 0) return reportedError;
|
|
1750
|
+
const moreThanOneRealChildren = validChildren.length > 1;
|
|
1751
|
+
let arrayLikeTargetParts: Type;
|
|
1752
|
+
let nonArrayLikeTargetParts: Type;
|
|
1753
|
+
const iterableType = getGlobalIterableType(c, false);
|
|
1754
|
+
if (iterableType !== c.emptyGenericType) {
|
|
1755
|
+
const anyIterable = createTypeFromGenericGlobalType(c, iterableType, [c.anyType, c.anyType, c.anyType]);
|
|
1756
|
+
arrayLikeTargetParts = filterType(c, childrenTargetType, (t) => isTypeAssignableTo(c, t, anyIterable));
|
|
1757
|
+
nonArrayLikeTargetParts = filterType(c, childrenTargetType, (t) => !isTypeAssignableTo(c, t, anyIterable));
|
|
1758
|
+
} else {
|
|
1759
|
+
arrayLikeTargetParts = filterType(c, childrenTargetType, (t) => isArrayOrTupleLikeType(c, t));
|
|
1760
|
+
nonArrayLikeTargetParts = filterType(c, childrenTargetType, (t) => !isArrayOrTupleLikeType(c, t));
|
|
1761
|
+
}
|
|
1762
|
+
const textMessage =
|
|
1763
|
+
Diagnostics.X_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2;
|
|
1764
|
+
const textArgs = [
|
|
1765
|
+
getTextOfNode(opening.kind === SyntaxKind.JsxOpeningElement ? getTagNameOf(opening) : opening),
|
|
1766
|
+
childrenPropName,
|
|
1767
|
+
typeToString(c, childrenTargetType),
|
|
1768
|
+
];
|
|
1769
|
+
if (moreThanOneRealChildren) {
|
|
1770
|
+
if (arrayLikeTargetParts !== c.neverType) {
|
|
1771
|
+
const realSource = createTupleType(c, checkJsxChildren(c, containingElement, CheckMode.Normal));
|
|
1772
|
+
const children: JsxElaborationElement[] = [];
|
|
1773
|
+
let memberOffset = 0;
|
|
1774
|
+
const allChildren = containingElement.children.nodes;
|
|
1775
|
+
for (let i = 0; i < allChildren.length; i++) {
|
|
1776
|
+
const e = getElaborationElementForJsxChild(allChildren[i]!, getNumberLiteralType(c, i - memberOffset));
|
|
1777
|
+
if (e !== undefined) children.push(e);
|
|
1778
|
+
else memberOffset++;
|
|
1779
|
+
}
|
|
1780
|
+
reportedError =
|
|
1781
|
+
elaborateIterableOrArrayLikeTargetElementwise(
|
|
1782
|
+
c,
|
|
1783
|
+
children,
|
|
1784
|
+
realSource,
|
|
1785
|
+
arrayLikeTargetParts,
|
|
1786
|
+
relation,
|
|
1787
|
+
textMessage,
|
|
1788
|
+
textArgs,
|
|
1789
|
+
diagnosticOutput,
|
|
1790
|
+
) || reportedError;
|
|
1791
|
+
} else if (!isTypeRelatedTo(c, getIndexedAccessType(c, source, childrenNameType), childrenTargetType, relation)) {
|
|
1792
|
+
// Arity errors are reported both directly and through the output.
|
|
1793
|
+
const diagnostic = c.error(
|
|
1794
|
+
containingElement.openingElement.tagName,
|
|
1795
|
+
Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided,
|
|
1796
|
+
childrenPropName,
|
|
1797
|
+
typeToString(c, childrenTargetType),
|
|
1798
|
+
);
|
|
1799
|
+
reportDiagnostic(c, diagnostic, diagnosticOutput);
|
|
1800
|
+
reportedError = true;
|
|
1801
|
+
}
|
|
1802
|
+
} else if (nonArrayLikeTargetParts !== c.neverType) {
|
|
1803
|
+
const e = getElaborationElementForJsxChild(validChildren[0]!, childrenNameType);
|
|
1804
|
+
if (e !== undefined)
|
|
1805
|
+
reportedError =
|
|
1806
|
+
elaborateElement(
|
|
1807
|
+
c,
|
|
1808
|
+
source,
|
|
1809
|
+
target,
|
|
1810
|
+
relation,
|
|
1811
|
+
e.errorNode,
|
|
1812
|
+
e.innerExpression,
|
|
1813
|
+
e.nameType,
|
|
1814
|
+
undefined,
|
|
1815
|
+
e.isText ? textMessage : undefined,
|
|
1816
|
+
textArgs,
|
|
1817
|
+
diagnosticOutput,
|
|
1818
|
+
) || reportedError;
|
|
1819
|
+
} else if (!isTypeRelatedTo(c, getIndexedAccessType(c, source, childrenNameType), childrenTargetType, relation)) {
|
|
1820
|
+
const diagnostic = c.error(
|
|
1821
|
+
containingElement.openingElement.tagName,
|
|
1822
|
+
Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided,
|
|
1823
|
+
childrenPropName,
|
|
1824
|
+
typeToString(c, childrenTargetType),
|
|
1825
|
+
);
|
|
1826
|
+
reportDiagnostic(c, diagnostic, diagnosticOutput);
|
|
1827
|
+
reportedError = true;
|
|
1828
|
+
}
|
|
1829
|
+
return reportedError;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
function elaborateIterableOrArrayLikeTargetElementwise(
|
|
1833
|
+
c: Checker,
|
|
1834
|
+
elements: JsxElaborationElement[],
|
|
1835
|
+
source: Type,
|
|
1836
|
+
target: Type,
|
|
1837
|
+
relation: Relation,
|
|
1838
|
+
textMessage: DiagnosticMessage,
|
|
1839
|
+
textArgs: string[],
|
|
1840
|
+
diagnosticOutput: Diagnostic[] | undefined,
|
|
1841
|
+
): boolean {
|
|
1842
|
+
const tupleOrArrayLikeTargetParts = filterType(c, target, (t) => isArrayOrTupleLikeType(c, t));
|
|
1843
|
+
const nonTupleOrArrayLikeTargetParts = filterType(c, target, (t) => !isArrayOrTupleLikeType(c, t));
|
|
1844
|
+
// A non-array-like part means `Iterable` exists.
|
|
1845
|
+
const iterationType =
|
|
1846
|
+
nonTupleOrArrayLikeTargetParts !== c.neverType
|
|
1847
|
+
? getIterationTypeOfIterable(
|
|
1848
|
+
c,
|
|
1849
|
+
IterationUse.ForOf,
|
|
1850
|
+
IterationTypeKind.Yield,
|
|
1851
|
+
nonTupleOrArrayLikeTargetParts,
|
|
1852
|
+
undefined,
|
|
1853
|
+
)
|
|
1854
|
+
: undefined;
|
|
1855
|
+
let reportedError = false;
|
|
1856
|
+
for (const e of elements) {
|
|
1857
|
+
let targetPropType = iterationType;
|
|
1858
|
+
const targetIndexedPropType =
|
|
1859
|
+
tupleOrArrayLikeTargetParts !== c.neverType
|
|
1860
|
+
? getBestMatchIndexedAccessTypeOrUndefined(c, source, tupleOrArrayLikeTargetParts, e.nameType)
|
|
1861
|
+
: undefined;
|
|
1862
|
+
if (targetIndexedPropType !== undefined && (targetIndexedPropType.flags & TypeFlags.IndexedAccess) === 0)
|
|
1863
|
+
targetPropType =
|
|
1864
|
+
iterationType !== undefined ? getUnionType(c, [iterationType, targetIndexedPropType]) : targetIndexedPropType;
|
|
1865
|
+
if (targetPropType === undefined) continue;
|
|
1866
|
+
let sourcePropType = getIndexedAccessTypeOrUndefined(c, source, e.nameType, AccessFlags.None);
|
|
1867
|
+
if (sourcePropType === undefined) continue;
|
|
1868
|
+
if (checkTypeRelatedTo(c, sourcePropType, targetPropType, relation, undefined, undefined, undefined)) continue;
|
|
1869
|
+
const next = e.innerExpression;
|
|
1870
|
+
const elaborated =
|
|
1871
|
+
next !== undefined &&
|
|
1872
|
+
elaborateError(c, next, sourcePropType, targetPropType, relation, undefined, diagnosticOutput);
|
|
1873
|
+
reportedError = true;
|
|
1874
|
+
if (elaborated) continue;
|
|
1875
|
+
// Report on the child itself, with the expression's type when there is one.
|
|
1876
|
+
const specificSource =
|
|
1877
|
+
next !== undefined
|
|
1878
|
+
? checkExpressionForMutableLocationWithContextualType(c, next, sourcePropType)
|
|
1879
|
+
: sourcePropType;
|
|
1880
|
+
if (e.isText) {
|
|
1881
|
+
reportDiagnostic(c, createDiagnosticForNode(e.errorNode, textMessage, textArgs), diagnosticOutput);
|
|
1882
|
+
continue;
|
|
1883
|
+
}
|
|
1884
|
+
if (c.exactOptionalPropertyTypes && isExactOptionalPropertyMismatch(c, specificSource, targetPropType)) {
|
|
1885
|
+
reportDiagnostic(
|
|
1886
|
+
c,
|
|
1887
|
+
createDiagnosticForNode(
|
|
1888
|
+
e.errorNode,
|
|
1889
|
+
Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target,
|
|
1890
|
+
[typeToString(c, specificSource), typeToString(c, targetPropType)],
|
|
1891
|
+
),
|
|
1892
|
+
diagnosticOutput,
|
|
1893
|
+
);
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1896
|
+
const propName = getPropertyNameFromIndex(e.nameType);
|
|
1897
|
+
const targetProp = propName !== undefined ? getPropertyOfType(c, tupleOrArrayLikeTargetParts, propName) : undefined;
|
|
1898
|
+
const sourceProp = propName !== undefined ? getPropertyOfType(c, source, propName) : undefined;
|
|
1899
|
+
const targetIsOptional = targetProp !== undefined && (targetProp.flags & SymbolFlags.Optional) !== 0;
|
|
1900
|
+
const sourceIsOptional = sourceProp !== undefined && (sourceProp.flags & SymbolFlags.Optional) !== 0;
|
|
1901
|
+
targetPropType = removeMissingType(c, targetPropType, targetIsOptional);
|
|
1902
|
+
sourcePropType = removeMissingType(c, sourcePropType, targetIsOptional && sourceIsOptional);
|
|
1903
|
+
const result = checkTypeRelatedTo(
|
|
1904
|
+
c,
|
|
1905
|
+
specificSource,
|
|
1906
|
+
targetPropType,
|
|
1907
|
+
relation,
|
|
1908
|
+
e.errorNode,
|
|
1909
|
+
undefined,
|
|
1910
|
+
diagnosticOutput,
|
|
1911
|
+
);
|
|
1912
|
+
if (result && specificSource !== sourcePropType)
|
|
1913
|
+
checkTypeRelatedTo(c, sourcePropType, targetPropType, relation, e.errorNode, undefined, diagnosticOutput);
|
|
1914
|
+
}
|
|
1915
|
+
return reportedError;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
/** Suggests `htmlFor` for `for`, `className` for `class`, or a similar property name. */
|
|
1919
|
+
export function getSuggestedSymbolForNonexistentJSXAttribute(
|
|
1920
|
+
c: Checker,
|
|
1921
|
+
name: string,
|
|
1922
|
+
containingType: Type,
|
|
1923
|
+
): Symbol | undefined {
|
|
1924
|
+
const properties = getPropertiesOfType(c, containingType);
|
|
1925
|
+
const jsxSpecific = name === 'for' ? 'htmlFor' : name === 'class' ? 'className' : '';
|
|
1926
|
+
if (jsxSpecific !== '') for (const p of properties) if (p.name === jsxSpecific) return p;
|
|
1927
|
+
return getSpellingSuggestionForName(c, name, properties, SymbolFlags.Value);
|
|
1928
|
+
}
|