From 6714998e01f994ef0e82a911cb2186ade799138c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Oct 2020 14:17:24 -0700 Subject: [PATCH 1/5] Auto-include types for the jsx import source in the new jsx transforms --- src/compiler/checker.ts | 36 ++- src/compiler/moduleNameResolver.ts | 7 +- src/compiler/program.ts | 28 +- src/compiler/transformers/jsx.ts | 2 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 8 +- ...formCustomImport(jsx=react-jsx).errors.txt | 14 + ...mCustomImport(jsx=react-jsxdev).errors.txt | 14 + ...stomImportPragma(jsx=react-jsx).errors.txt | 26 ++ ...mImportPragma(jsx=react-jsxdev).errors.txt | 26 ++ ...PropCustomImport(jsx=react-jsx).errors.txt | 13 + ...pCustomImport(jsx=react-jsxdev).errors.txt | 13 + ...stomImportPragma(jsx=react-jsx).errors.txt | 24 ++ ...mImportPragma(jsx=react-jsxdev).errors.txt | 24 ++ .../jsxNamespaceImplicitImportJSXNamespace.js | 110 +++++++ ...amespaceImplicitImportJSXNamespace.symbols | 298 ++++++++++++++++++ ...xNamespaceImplicitImportJSXNamespace.types | 210 ++++++++++++ ...jsxNamespaceImplicitImportJSXNamespace.tsx | 103 ++++++ tests/lib/react16.d.ts | 16 +- 19 files changed, 955 insertions(+), 18 deletions(-) create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).errors.txt create mode 100644 tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).errors.txt create mode 100644 tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.js create mode 100644 tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.symbols create mode 100644 tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types create mode 100644 tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afb1e6364b5aa..37be1ae713d3c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25132,6 +25132,31 @@ namespace ts { return links.resolvedSymbol; } + function getJsxNamespaceContainerForImplicitImport(location: Node | undefined): Symbol | undefined { + const file = location && getSourceFileOfNode(location); + const links = file && getNodeLinks(file); + if (links && links.jsxImplicitImportContainer === false) { + return undefined; + } + if (links && links.jsxImplicitImportContainer) { + return links.jsxImplicitImportContainer; + } + const runtimeImportSpecifier = getJSXRuntimeImport(getJSXImplicitImportBase(compilerOptions, file), compilerOptions); + if (!runtimeImportSpecifier) { + return undefined; + } + const isClassic = getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Classic; + const errorMessage = isClassic + ? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_node_or_to_add_aliases_to_the_paths_option + : Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations; + const mod = resolveExternalModule(location!, runtimeImportSpecifier, errorMessage, location!); + const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined; + if (links) { + links.jsxImplicitImportContainer = result || false; + } + return result; + } + function getJsxNamespaceAt(location: Node | undefined): Symbol { const links = location && getNodeLinks(location); if (links && links.jsxNamespace) { @@ -25139,7 +25164,10 @@ namespace ts { } if (!links || links.jsxNamespace !== false) { const namespaceName = getJsxNamespace(location); - const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); + let resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); + if (!resolvedNamespace || resolvedNamespace === unknownSymbol) { + resolvedNamespace = getJsxNamespaceContainerForImplicitImport(location); + } if (resolvedNamespace) { const candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, SymbolFlags.Namespace)); if (candidate && candidate !== unknownSymbol) { @@ -25148,9 +25176,9 @@ namespace ts { } return candidate; } - if (links) { - links.jsxNamespace = false; - } + } + if (links) { + links.jsxNamespace = false; } } // JSX global fallback diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index fbd4f57a4a0fb..5928fb564868a 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -402,8 +402,10 @@ namespace ts { */ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] { // Use explicit type list from tsconfig.json + // jsxImportSource, if present and in use, creates implicit imports + const implicitImport = getJSXRuntimeImport(getJSXImplicitImportBase(options), options); if (options.types) { - return options.types; + return [...options.types, ...(implicitImport ? [implicitImport] : [])]; } // Walk the primary type lookup locations @@ -434,6 +436,9 @@ namespace ts { } } } + if (implicitImport) { + result.push(implicitImport); + } return result; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 396c4d8d84cef..bc358a425322d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1494,7 +1494,7 @@ namespace ts { } // try to verify results of module resolution for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) { - const moduleNames = getModuleNames(newSourceFile); + const moduleNames = getModuleNames(newSourceFile, options); const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile); // ensure that module resolution results are still correct const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo); @@ -2840,11 +2840,16 @@ namespace ts { if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--; } else { - fileProcessingDiagnostics.add(createRefFileDiagnostic( - refFile, - Diagnostics.Cannot_find_type_definition_file_for_0, - typeReferenceDirective - )); + // Don't issue an error when auto-inclusion lookup fails for the jsxImportSource (at this point) + // It may be provided by an ambient module in the compilation, instead. + // A usage of a JSX tag later should report that the module couldn't be resolved if it is not supplied. + if (refFile || typeReferenceDirective !== getJSXRuntimeImport(getJSXImplicitImportBase(options), options)) { + fileProcessingDiagnostics.add(createRefFileDiagnostic( + refFile, + Diagnostics.Cannot_find_type_definition_file_for_0, + typeReferenceDirective + )); + } } if (saveResolution) { @@ -2891,9 +2896,9 @@ namespace ts { function processImportedModules(file: SourceFile) { collectExternalModuleReferences(file); - if (file.imports.length || file.moduleAugmentations.length) { + if (file.imports.length || file.moduleAugmentations.length || getJSXImplicitImportBase(options, file)) { // Because global augmentation doesn't have string literal name, we can check for global augmentation as such. - const moduleNames = getModuleNames(file); + const moduleNames = getModuleNames(file, options); const resolutions = resolveModuleNamesReusingOldState(moduleNames, file); Debug.assert(resolutions.length === moduleNames.length); for (let i = 0; i < moduleNames.length; i++) { @@ -3882,7 +3887,8 @@ namespace ts { } } - function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] { + function getModuleNames(file: SourceFile, options: CompilerOptions): string[] { + const { imports, moduleAugmentations } = file; const res = imports.map(i => i.text); for (const aug of moduleAugmentations) { if (aug.kind === SyntaxKind.StringLiteral) { @@ -3890,6 +3896,10 @@ namespace ts { } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. } + const jsxRuntimeImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); + if (jsxRuntimeImport) { + res.push(jsxRuntimeImport); + } return res; } } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index bb177d518bb7a..9814f29b2a28f 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -42,7 +42,7 @@ namespace ts { function getImplicitImportForName(name: string) { const importSource = name === "createElement" ? currentFileState.importSpecifier! - : `${currentFileState.importSpecifier}/${compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime"}`; + : getJSXRuntimeImport(currentFileState.importSpecifier, compilerOptions)!; const existing = currentFileState.utilizedImplicitRuntimeImports?.get(importSource)?.get(name); if (existing) { return existing.name; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 750934077595f..a234916d5c13a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4843,6 +4843,7 @@ namespace ts { resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference switchTypes?: Type[]; // Cached array of switch case expression types jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node + jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive deferredNodes?: ESMap; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3326de196896b..2dc1fb0475d34 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6009,8 +6009,8 @@ namespace ts { return jsx === JsxEmit.React || jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev; } - export function getJSXImplicitImportBase(compilerOptions: CompilerOptions, file: SourceFile): string | undefined { - const jsxImportSourcePragmas = file.pragmas.get("jsximportsource"); + export function getJSXImplicitImportBase(compilerOptions: CompilerOptions, file?: SourceFile): string | undefined { + const jsxImportSourcePragmas = file?.pragmas.get("jsximportsource"); const jsxImportSourcePragma = isArray(jsxImportSourcePragmas) ? jsxImportSourcePragmas[0] : jsxImportSourcePragmas; return compilerOptions.jsx === JsxEmit.ReactJSX || compilerOptions.jsx === JsxEmit.ReactJSXDev || @@ -6020,6 +6020,10 @@ namespace ts { undefined; } + export function getJSXRuntimeImport(base: string | undefined, options: CompilerOptions) { + return base ? `${base}/${options.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime"}` : undefined; + } + export function hasZeroOrOneAsteriskCharacter(str: string): boolean { let seenAsterisk = false; for (let i = 0; i < str.length; i++) { diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt new file mode 100644 index 0000000000000..7df2a08fa56cf --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformCustomImport.tsx (1 errors) ==== + /// + const a = <> + ~~ +!!! error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. +

+ text +
+ + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt new file mode 100644 index 0000000000000..08d0f538c07d8 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformCustomImport.tsx(2,11): error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformCustomImport.tsx (1 errors) ==== + /// + const a = <> + ~~ +!!! error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. +

+ text +
+ + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt new file mode 100644 index 0000000000000..40ac677906e92 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/jsx/jsxs/preact.tsx(3,11): error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/react.tsx (0 errors) ==== + /// + /* @jsxImportSource react */ + import "./preact"; + const a = <> +

+ text +
+ + + export {}; +==== tests/cases/conformance/jsx/jsxs/preact.tsx (1 errors) ==== + /// + /* @jsxImportSource preact */ + const a = <> + ~~ +!!! error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. +

+ text +
+ + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt new file mode 100644 index 0000000000000..ee21bc25e6064 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/jsx/jsxs/preact.tsx(3,11): error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/react.tsx (0 errors) ==== + /// + /* @jsxImportSource react */ + import "./preact"; + const a = <> +

+ text +
+ + + export {}; +==== tests/cases/conformance/jsx/jsxs/preact.tsx (1 errors) ==== + /// + /* @jsxImportSource preact */ + const a = <> + ~~ +!!! error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. +

+ text +
+ + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).errors.txt new file mode 100644 index 0000000000000..0a4a1dfee7ba1 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformKeyPropCustomImport.tsx(3,11): error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformKeyPropCustomImport.tsx (1 errors) ==== + /// + const props = { answer: 42 } + const a =
text
; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + const b =
text
; + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).errors.txt new file mode 100644 index 0000000000000..602ca693375ba --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformKeyPropCustomImport.tsx(3,11): error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformKeyPropCustomImport.tsx (1 errors) ==== + /// + const props = { answer: 42 } + const a =
text
; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + const b =
text
; + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).errors.txt new file mode 100644 index 0000000000000..2b670f3401449 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/jsx/jsxs/preact.tsx(4,11): error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/react.tsx (0 errors) ==== + /// + /* @jsxImportSource react */ + import "./preact"; + const props2 = { answer: 42 } + const a2 =
text
; + const b2 =
text
; + + export {}; + +==== tests/cases/conformance/jsx/jsxs/preact.tsx (1 errors) ==== + /// + /* @jsxImportSource preact */ + const props = { answer: 42 } + const a =
text
; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'preact/jsx-runtime' or its corresponding type declarations. + const b =
text
; + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).errors.txt b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).errors.txt new file mode 100644 index 0000000000000..ba077fe5225d7 --- /dev/null +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/jsx/jsxs/preact.tsx(4,11): error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + + +==== tests/cases/conformance/jsx/jsxs/react.tsx (0 errors) ==== + /// + /* @jsxImportSource react */ + import "./preact"; + const props2 = { answer: 42 } + const a2 =
text
; + const b2 =
text
; + + export {}; + +==== tests/cases/conformance/jsx/jsxs/preact.tsx (1 errors) ==== + /// + /* @jsxImportSource preact */ + const props = { answer: 42 } + const a =
text
; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'preact/jsx-dev-runtime' or its corresponding type declarations. + const b =
text
; + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.js b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.js new file mode 100644 index 0000000000000..68e607e069d7f --- /dev/null +++ b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.js @@ -0,0 +1,110 @@ +//// [tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx] //// + +//// [index.d.ts] +type Defaultize = + // Distribute over unions + Props extends any // Make any properties included in Default optional + ? Partial>> & + // Include the remaining properties from Props + Pick> + : never; +export namespace JSXInternal { + interface HTMLAttributes { } + interface SVGAttributes { } + type LibraryManagedAttributes = Component extends { + defaultProps: infer Defaults; + } + ? Defaultize + : Props; + + interface IntrinsicAttributes { + key?: any; + } + + interface Element extends VNode { } + + interface ElementClass extends Component { } + + interface ElementAttributesProperty { + props: any; + } + + interface ElementChildrenAttribute { + children: any; + } + + interface IntrinsicElements { + div: HTMLAttributes; + } +} +export const Fragment: unique symbol; +export type ComponentType = {}; +export type ComponentChild = {}; +export type ComponentChildren = {}; +export type VNode = {}; +export type Attributes = {}; +export type Component = {}; +//// [index.d.ts] +export { Fragment } from '..'; +import { + ComponentType, + ComponentChild, + ComponentChildren, + VNode, + Attributes +} from '..'; +import { JSXInternal } from '..'; + +export function jsx( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChild }, + key?: string +): VNode; +export function jsx

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChild }, + key?: string +): VNode; + + +export function jsxs( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChild[] }, + key?: string +): VNode; +export function jsxs

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChild[] }, + key?: string +): VNode; + + +export function jsxDEV( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChildren }, + key?: string +): VNode; +export function jsxDEV

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChildren }, + key?: string +): VNode; + +export import JSX = JSXInternal; + +//// [index.tsx] +export const Comp = () =>

; + +//// [index.js] +"use strict"; +exports.__esModule = true; +exports.Comp = void 0; +var jsx_runtime_1 = require("preact/jsx-runtime"); +var Comp = function () { return jsx_runtime_1.jsx("div", {}, void 0); }; +exports.Comp = Comp; diff --git a/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.symbols b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.symbols new file mode 100644 index 0000000000000..b3524f1af8074 --- /dev/null +++ b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.symbols @@ -0,0 +1,298 @@ +=== /node_modules/preact/index.d.ts === +type Defaultize = +>Defaultize : Symbol(Defaultize, Decl(index.d.ts, 0, 0)) +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) +>Defaults : Symbol(Defaults, Decl(index.d.ts, 0, 22)) + + // Distribute over unions + Props extends any // Make any properties included in Default optional +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) + + ? Partial>> & +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) +>Defaults : Symbol(Defaults, Decl(index.d.ts, 0, 22)) + + // Include the remaining properties from Props + Pick> +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(index.d.ts, 0, 16)) +>Defaults : Symbol(Defaults, Decl(index.d.ts, 0, 22)) + + : never; +export namespace JSXInternal { +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 6, 10)) + + interface HTMLAttributes { } +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 7, 30)) +>T : Symbol(T, Decl(index.d.ts, 8, 29)) + + interface SVGAttributes { } +>SVGAttributes : Symbol(SVGAttributes, Decl(index.d.ts, 8, 40)) +>T : Symbol(T, Decl(index.d.ts, 9, 28)) + + type LibraryManagedAttributes = Component extends { +>LibraryManagedAttributes : Symbol(LibraryManagedAttributes, Decl(index.d.ts, 9, 39)) +>Component : Symbol(Component, Decl(index.d.ts, 10, 34)) +>Props : Symbol(Props, Decl(index.d.ts, 10, 44)) +>Component : Symbol(Component, Decl(index.d.ts, 10, 34)) + + defaultProps: infer Defaults; +>defaultProps : Symbol(defaultProps, Decl(index.d.ts, 10, 73)) +>Defaults : Symbol(Defaults, Decl(index.d.ts, 11, 27)) + } + ? Defaultize +>Defaultize : Symbol(Defaultize, Decl(index.d.ts, 0, 0)) +>Props : Symbol(Props, Decl(index.d.ts, 10, 44)) +>Defaults : Symbol(Defaults, Decl(index.d.ts, 11, 27)) + + : Props; +>Props : Symbol(Props, Decl(index.d.ts, 10, 44)) + + interface IntrinsicAttributes { +>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(index.d.ts, 14, 16)) + + key?: any; +>key : Symbol(IntrinsicAttributes.key, Decl(index.d.ts, 16, 35)) + } + + interface Element extends VNode { } +>Element : Symbol(Element, Decl(index.d.ts, 18, 5)) +>VNode : Symbol(VNode, Decl(index.d.ts, 39, 35)) + + interface ElementClass extends Component { } +>ElementClass : Symbol(ElementClass, Decl(index.d.ts, 20, 44)) +>Component : Symbol(Component, Decl(index.d.ts, 41, 28)) + + interface ElementAttributesProperty { +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(index.d.ts, 22, 58)) + + props: any; +>props : Symbol(ElementAttributesProperty.props, Decl(index.d.ts, 24, 41)) + } + + interface ElementChildrenAttribute { +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(index.d.ts, 26, 5)) + + children: any; +>children : Symbol(ElementChildrenAttribute.children, Decl(index.d.ts, 28, 40)) + } + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 30, 5)) + + div: HTMLAttributes; +>div : Symbol(IntrinsicElements.div, Decl(index.d.ts, 32, 33)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 7, 30)) + } +} +export const Fragment: unique symbol; +>Fragment : Symbol(Fragment, Decl(index.d.ts, 36, 12)) + +export type ComponentType = {}; +>ComponentType : Symbol(ComponentType, Decl(index.d.ts, 36, 37)) +>T : Symbol(T, Decl(index.d.ts, 37, 26)) + +export type ComponentChild = {}; +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 37, 39)) + +export type ComponentChildren = {}; +>ComponentChildren : Symbol(ComponentChildren, Decl(index.d.ts, 38, 32)) + +export type VNode = {}; +>VNode : Symbol(VNode, Decl(index.d.ts, 39, 35)) +>T : Symbol(T, Decl(index.d.ts, 40, 18)) + +export type Attributes = {}; +>Attributes : Symbol(Attributes, Decl(index.d.ts, 40, 31)) + +export type Component = {}; +>Component : Symbol(Component, Decl(index.d.ts, 41, 28)) +>T : Symbol(T, Decl(index.d.ts, 42, 22)) +>U : Symbol(U, Decl(index.d.ts, 42, 29)) + +=== /node_modules/preact/jsx-runtime/index.d.ts === +export { Fragment } from '..'; +>Fragment : Symbol(Fragment, Decl(index.d.ts, 0, 8)) + +import { + ComponentType, +>ComponentType : Symbol(ComponentType, Decl(index.d.ts, 1, 8)) + + ComponentChild, +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 2, 18)) + + ComponentChildren, +>ComponentChildren : Symbol(ComponentChildren, Decl(index.d.ts, 3, 19)) + + VNode, +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + + Attributes +>Attributes : Symbol(Attributes, Decl(index.d.ts, 5, 10)) + +} from '..'; +import { JSXInternal } from '..'; +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) + +export function jsx( +>jsx : Symbol(jsx, Decl(index.d.ts, 8, 33), Decl(index.d.ts, 16, 14)) + + type: string, +>type : Symbol(type, Decl(index.d.ts, 10, 20)) + + props: JSXInternal.HTMLAttributes & +>props : Symbol(props, Decl(index.d.ts, 11, 17)) +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>HTMLAttributes : Symbol(JSXInternal.HTMLAttributes, Decl(index.d.ts, 7, 30)) + + JSXInternal.SVGAttributes & +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>SVGAttributes : Symbol(JSXInternal.SVGAttributes, Decl(index.d.ts, 8, 40)) + + Record & { children?: ComponentChild }, +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>children : Symbol(children, Decl(index.d.ts, 14, 31)) +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 2, 18)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 14, 60)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + +export function jsx

( +>jsx : Symbol(jsx, Decl(index.d.ts, 8, 33), Decl(index.d.ts, 16, 14)) +>P : Symbol(P, Decl(index.d.ts, 17, 20)) + + type: ComponentType

, +>type : Symbol(type, Decl(index.d.ts, 17, 23)) +>ComponentType : Symbol(ComponentType, Decl(index.d.ts, 1, 8)) +>P : Symbol(P, Decl(index.d.ts, 17, 20)) + + props: Attributes & P & { children?: ComponentChild }, +>props : Symbol(props, Decl(index.d.ts, 18, 27)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 5, 10)) +>P : Symbol(P, Decl(index.d.ts, 17, 20)) +>children : Symbol(children, Decl(index.d.ts, 19, 29)) +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 2, 18)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 19, 58)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + + +export function jsxs( +>jsxs : Symbol(jsxs, Decl(index.d.ts, 21, 14), Decl(index.d.ts, 30, 14)) + + type: string, +>type : Symbol(type, Decl(index.d.ts, 24, 21)) + + props: JSXInternal.HTMLAttributes & +>props : Symbol(props, Decl(index.d.ts, 25, 17)) +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>HTMLAttributes : Symbol(JSXInternal.HTMLAttributes, Decl(index.d.ts, 7, 30)) + + JSXInternal.SVGAttributes & +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>SVGAttributes : Symbol(JSXInternal.SVGAttributes, Decl(index.d.ts, 8, 40)) + + Record & { children?: ComponentChild[] }, +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>children : Symbol(children, Decl(index.d.ts, 28, 31)) +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 2, 18)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 28, 62)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + +export function jsxs

( +>jsxs : Symbol(jsxs, Decl(index.d.ts, 21, 14), Decl(index.d.ts, 30, 14)) +>P : Symbol(P, Decl(index.d.ts, 31, 21)) + + type: ComponentType

, +>type : Symbol(type, Decl(index.d.ts, 31, 24)) +>ComponentType : Symbol(ComponentType, Decl(index.d.ts, 1, 8)) +>P : Symbol(P, Decl(index.d.ts, 31, 21)) + + props: Attributes & P & { children?: ComponentChild[] }, +>props : Symbol(props, Decl(index.d.ts, 32, 27)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 5, 10)) +>P : Symbol(P, Decl(index.d.ts, 31, 21)) +>children : Symbol(children, Decl(index.d.ts, 33, 29)) +>ComponentChild : Symbol(ComponentChild, Decl(index.d.ts, 2, 18)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 33, 60)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + + +export function jsxDEV( +>jsxDEV : Symbol(jsxDEV, Decl(index.d.ts, 35, 14), Decl(index.d.ts, 44, 14)) + + type: string, +>type : Symbol(type, Decl(index.d.ts, 38, 23)) + + props: JSXInternal.HTMLAttributes & +>props : Symbol(props, Decl(index.d.ts, 39, 17)) +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>HTMLAttributes : Symbol(JSXInternal.HTMLAttributes, Decl(index.d.ts, 7, 30)) + + JSXInternal.SVGAttributes & +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) +>SVGAttributes : Symbol(JSXInternal.SVGAttributes, Decl(index.d.ts, 8, 40)) + + Record & { children?: ComponentChildren }, +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>children : Symbol(children, Decl(index.d.ts, 42, 31)) +>ComponentChildren : Symbol(ComponentChildren, Decl(index.d.ts, 3, 19)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 42, 63)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + +export function jsxDEV

( +>jsxDEV : Symbol(jsxDEV, Decl(index.d.ts, 35, 14), Decl(index.d.ts, 44, 14)) +>P : Symbol(P, Decl(index.d.ts, 45, 23)) + + type: ComponentType

, +>type : Symbol(type, Decl(index.d.ts, 45, 26)) +>ComponentType : Symbol(ComponentType, Decl(index.d.ts, 1, 8)) +>P : Symbol(P, Decl(index.d.ts, 45, 23)) + + props: Attributes & P & { children?: ComponentChildren }, +>props : Symbol(props, Decl(index.d.ts, 46, 27)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 5, 10)) +>P : Symbol(P, Decl(index.d.ts, 45, 23)) +>children : Symbol(children, Decl(index.d.ts, 47, 29)) +>ComponentChildren : Symbol(ComponentChildren, Decl(index.d.ts, 3, 19)) + + key?: string +>key : Symbol(key, Decl(index.d.ts, 47, 61)) + +): VNode; +>VNode : Symbol(VNode, Decl(index.d.ts, 4, 22)) + +export import JSX = JSXInternal; +>JSX : Symbol(JSX, Decl(index.d.ts, 49, 14)) +>JSXInternal : Symbol(JSXInternal, Decl(index.d.ts, 8, 8)) + +=== /index.tsx === +export const Comp = () =>

; +>Comp : Symbol(Comp, Decl(index.tsx, 0, 12)) +>div : Symbol(JSXInternal.IntrinsicElements.div, Decl(index.d.ts, 32, 33)) +>div : Symbol(JSXInternal.IntrinsicElements.div, Decl(index.d.ts, 32, 33)) + diff --git a/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types new file mode 100644 index 0000000000000..8869f10731bb5 --- /dev/null +++ b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types @@ -0,0 +1,210 @@ +=== /node_modules/preact/index.d.ts === +type Defaultize = +>Defaultize : Defaultize + + // Distribute over unions + Props extends any // Make any properties included in Default optional + ? Partial>> & + // Include the remaining properties from Props + Pick> + : never; +export namespace JSXInternal { + interface HTMLAttributes { } + interface SVGAttributes { } + type LibraryManagedAttributes = Component extends { +>LibraryManagedAttributes : LibraryManagedAttributes + + defaultProps: infer Defaults; +>defaultProps : Defaults + } + ? Defaultize + : Props; + + interface IntrinsicAttributes { + key?: any; +>key : any + } + + interface Element extends VNode { } + + interface ElementClass extends Component { } + + interface ElementAttributesProperty { + props: any; +>props : any + } + + interface ElementChildrenAttribute { + children: any; +>children : any + } + + interface IntrinsicElements { + div: HTMLAttributes; +>div : HTMLAttributes<{}> + } +} +export const Fragment: unique symbol; +>Fragment : unique symbol + +export type ComponentType = {}; +>ComponentType : ComponentType + +export type ComponentChild = {}; +>ComponentChild : ComponentChild + +export type ComponentChildren = {}; +>ComponentChildren : ComponentChildren + +export type VNode = {}; +>VNode : VNode + +export type Attributes = {}; +>Attributes : Attributes + +export type Component = {}; +>Component : Component + +=== /node_modules/preact/jsx-runtime/index.d.ts === +export { Fragment } from '..'; +>Fragment : unique symbol + +import { + ComponentType, +>ComponentType : any + + ComponentChild, +>ComponentChild : any + + ComponentChildren, +>ComponentChildren : any + + VNode, +>VNode : any + + Attributes +>Attributes : any + +} from '..'; +import { JSXInternal } from '..'; +>JSXInternal : any + +export function jsx( +>jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode; } + + type: string, +>type : string + + props: JSXInternal.HTMLAttributes & +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; } +>JSXInternal : any + + JSXInternal.SVGAttributes & +>JSXInternal : any + + Record & { children?: ComponentChild }, +>children : ComponentChild | undefined + + key?: string +>key : string | undefined + +): VNode; +export function jsx

( +>jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } + + type: ComponentType

, +>type : ComponentType

+ + props: Attributes & P & { children?: ComponentChild }, +>props : P & { children?: ComponentChild | undefined; } +>children : ComponentChild | undefined + + key?: string +>key : string | undefined + +): VNode; + + +export function jsxs( +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode; } + + type: string, +>type : string + + props: JSXInternal.HTMLAttributes & +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; } +>JSXInternal : any + + JSXInternal.SVGAttributes & +>JSXInternal : any + + Record & { children?: ComponentChild[] }, +>children : ComponentChild[] | undefined + + key?: string +>key : string | undefined + +): VNode; +export function jsxs

( +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } + + type: ComponentType

, +>type : ComponentType

+ + props: Attributes & P & { children?: ComponentChild[] }, +>props : P & { children?: ComponentChild[] | undefined; } +>children : ComponentChild[] | undefined + + key?: string +>key : string | undefined + +): VNode; + + +export function jsxDEV( +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode; } + + type: string, +>type : string + + props: JSXInternal.HTMLAttributes & +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; } +>JSXInternal : any + + JSXInternal.SVGAttributes & +>JSXInternal : any + + Record & { children?: ComponentChildren }, +>children : ComponentChildren | undefined + + key?: string +>key : string | undefined + +): VNode; +export function jsxDEV

( +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } + + type: ComponentType

, +>type : ComponentType

+ + props: Attributes & P & { children?: ComponentChildren }, +>props : P & { children?: ComponentChildren | undefined; } +>children : ComponentChildren | undefined + + key?: string +>key : string | undefined + +): VNode; + +export import JSX = JSXInternal; +>JSX : any +>JSXInternal : error + +=== /index.tsx === +export const Comp = () =>

; +>Comp : () => import("/node_modules/preact/index").JSXInternal.Element +>() =>
: () => import("/node_modules/preact/index").JSXInternal.Element +>
: import("/node_modules/preact/index").JSXInternal.Element +>div : any +>div : any + diff --git a/tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx b/tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx new file mode 100644 index 0000000000000..d2810ed06a2cc --- /dev/null +++ b/tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx @@ -0,0 +1,103 @@ +// @strict: true +// @jsx: react-jsx +// @jsxImportSource: preact +// @filename: /node_modules/preact/index.d.ts +type Defaultize = + // Distribute over unions + Props extends any // Make any properties included in Default optional + ? Partial>> & + // Include the remaining properties from Props + Pick> + : never; +export namespace JSXInternal { + interface HTMLAttributes { } + interface SVGAttributes { } + type LibraryManagedAttributes = Component extends { + defaultProps: infer Defaults; + } + ? Defaultize + : Props; + + interface IntrinsicAttributes { + key?: any; + } + + interface Element extends VNode { } + + interface ElementClass extends Component { } + + interface ElementAttributesProperty { + props: any; + } + + interface ElementChildrenAttribute { + children: any; + } + + interface IntrinsicElements { + div: HTMLAttributes; + } +} +export const Fragment: unique symbol; +export type ComponentType = {}; +export type ComponentChild = {}; +export type ComponentChildren = {}; +export type VNode = {}; +export type Attributes = {}; +export type Component = {}; +// @filename: /node_modules/preact/jsx-runtime/index.d.ts +export { Fragment } from '..'; +import { + ComponentType, + ComponentChild, + ComponentChildren, + VNode, + Attributes +} from '..'; +import { JSXInternal } from '..'; + +export function jsx( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChild }, + key?: string +): VNode; +export function jsx

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChild }, + key?: string +): VNode; + + +export function jsxs( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChild[] }, + key?: string +): VNode; +export function jsxs

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChild[] }, + key?: string +): VNode; + + +export function jsxDEV( + type: string, + props: JSXInternal.HTMLAttributes & + JSXInternal.SVGAttributes & + Record & { children?: ComponentChildren }, + key?: string +): VNode; +export function jsxDEV

( + type: ComponentType

, + props: Attributes & P & { children?: ComponentChildren }, + key?: string +): VNode; + +export import JSX = JSXInternal; + +// @filename: /index.tsx +export const Comp = () =>

; \ No newline at end of file diff --git a/tests/lib/react16.d.ts b/tests/lib/react16.d.ts index 4b91fb0c6fed9..ce59d6ea86a58 100644 --- a/tests/lib/react16.d.ts +++ b/tests/lib/react16.d.ts @@ -2566,4 +2566,18 @@ declare module "react" { } } } -} \ No newline at end of file +} + +declare module "react/jsx-runtime" { + import * as React from "react"; + export function jsx(...args: any): React.ReactElement; + export function jsxs(...args: any): React.ReactElement; + export import Fragment = React.Fragment; +} + + +declare module "react/jsx-dev-runtime" { + import * as React from "react"; + export function jsxDEV(...args: any): React.ReactElement; + export import Fragment = React.Fragment; +} From fe3b3436e658528dfeca2ccc7d635776c6a0931b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2020 15:38:20 -0700 Subject: [PATCH 2/5] Add affectsModuleResolution: true ot jsx and jsxImportSource options --- src/compiler/commandLineParser.ts | 2 ++ .../programUpdates/updates-emit-on-jsx-option-change.js | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 56cc83516e5a0..1698ee97a72ff 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -382,6 +382,7 @@ namespace ts { type: jsxOptionMap, affectsSourceFile: true, affectsEmit: true, + affectsModuleResolution: true, paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, @@ -802,6 +803,7 @@ namespace ts { { name: "jsxImportSource", type: "string", + affectsModuleResolution: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_the_module_specifier_to_be_used_to_import_the_jsx_and_jsxs_factory_functions_from_eg_react }, diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-emit-on-jsx-option-change.js b/tests/baselines/reference/tscWatch/programUpdates/updates-emit-on-jsx-option-change.js index 914da8324999a..6ac860391b983 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/updates-emit-on-jsx-option-change.js +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-emit-on-jsx-option-change.js @@ -80,7 +80,7 @@ Output:: Program root files: ["/user/username/projects/myproject/index.tsx"] Program options: {"jsx":2,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} -Program structureReused: Completely +Program structureReused: Not Program files:: /a/lib/lib.d.ts /user/username/projects/myproject/index.tsx @@ -98,10 +98,10 @@ WatchedFiles:: FsWatches:: FsWatchesRecursive:: -/user/username/projects/myproject/node_modules/@types: - {"directoryName":"/user/username/projects/myproject/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} /user/username/projects/myproject: {"directoryName":"/user/username/projects/myproject","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject/node_modules/@types: + {"directoryName":"/user/username/projects/myproject/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} exitCode:: ExitStatus.undefined From 8493ee88249682866178a151cf649bbd8081fce0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2020 16:01:27 -0700 Subject: [PATCH 3/5] Add mroe incremental-affecting affixes to compiler options, add incremental test for changing jsxImportSource --- src/compiler/commandLineParser.ts | 2 + .../unittests/tscWatch/incremental.ts | 28 ++ ...ImportSource-option-changed-incremental.js | 248 +++++++++++++++ .../jsxImportSource-option-changed-watch.js | 285 ++++++++++++++++++ 4 files changed, 563 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js create mode 100644 tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 1698ee97a72ff..2c41ba05ffde6 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -803,6 +803,8 @@ namespace ts { { name: "jsxImportSource", type: "string", + affectsSemanticDiagnostics: true, + affectsEmit: true, affectsModuleResolution: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_the_module_specifier_to_be_used_to_import_the_jsx_and_jsxs_factory_functions_from_eg_react diff --git a/src/testRunner/unittests/tscWatch/incremental.ts b/src/testRunner/unittests/tscWatch/incremental.ts index f4b7fa13ed413..5aca68f749d68 100644 --- a/src/testRunner/unittests/tscWatch/incremental.ts +++ b/src/testRunner/unittests/tscWatch/incremental.ts @@ -276,5 +276,33 @@ export interface A { ], modifyFs: host => host.deleteFile(`${project}/globals.d.ts`) }); + + const jsxImportSourceOptions = { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" }; + const jsxLibraryContent = `export namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { + propA?: boolean; + }; + } +} +export function jsx(...args: any[]): void; +export function jsxs(...args: any[]): void; +export const Fragment: unique symbol; +`; + + verifyIncrementalWatchEmit({ + subScenario: "jsxImportSource option changed", + files: () => [ + { path: libFile.path, content: libContent }, + { path: `${project}/node_modules/react/jsx-runtime/index.d.ts`, content: jsxLibraryContent }, + { path: `${project}/node_modules/react/package.json`, content: JSON.stringify({ name: "react", version: "0.0.1" }) }, + { path: `${project}/node_modules/preact/jsx-runtime/index.d.ts`, content: jsxLibraryContent.replace("propA", "propB") }, + { path: `${project}/node_modules/preact/package.json`, content: JSON.stringify({ name: "preact", version: "0.0.1" }) }, + { path: `${project}/index.tsx`, content: `export const App = () =>
;` }, + { path: configFile.path, content: JSON.stringify({ compilerOptions: jsxImportSourceOptions }) } + ], + modifyFs: host => host.writeFile(configFile.path, JSON.stringify({ compilerOptions: { ...jsxImportSourceOptions, jsxImportSource: "preact" } })) + }); }); } diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js new file mode 100644 index 0000000000000..e75b1813ec968 --- /dev/null +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js @@ -0,0 +1,248 @@ +Input:: +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts] +export namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { + propA?: boolean; + }; + } +} +export function jsx(...args: any[]): void; +export function jsxs(...args: any[]): void; +export const Fragment: unique symbol; + + +//// [/users/username/projects/project/node_modules/react/package.json] +{"name":"react","version":"0.0.1"} + +//// [/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts] +export namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { + propB?: boolean; + }; + } +} +export function jsx(...args: any[]): void; +export function jsxs(...args: any[]): void; +export const Fragment: unique symbol; + + +//// [/users/username/projects/project/node_modules/preact/package.json] +{"name":"preact","version":"0.0.1"} + +//// [/users/username/projects/project/index.tsx] +export const App = () =>
; + +//// [/users/username/projects/project/tsconfig.json] +{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"react"}} + + +/a/lib/tsc.js -i +Output:: + + +Program root files: ["/users/username/projects/project/index.tsx"] +Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react","configFilePath":"/users/username/projects/project/tsconfig.json"} +Program structureReused: Not +Program files:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts + +WatchedFiles:: + +FsWatches:: + +FsWatchesRecursive:: + +exitCode:: ExitStatus.Success + +//// [/users/username/projects/project/index.js] +"use strict"; +exports.__esModule = true; +exports.App = void 0; +var jsx_runtime_1 = require("react/jsx-runtime"); +var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); }; +exports.App = App; + + +//// [/users/username/projects/project/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../a/lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false + }, + "./node_modules/react/jsx-runtime/index.d.ts": { + "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "affectsGlobalScope": false + } + }, + "options": { + "module": 1, + "jsx": 4, + "incremental": true, + "jsxImportSource": "react", + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": { + "./index.tsx": [ + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../../../a/lib/lib.d.ts", + "./index.tsx", + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "version": "FakeTSVersion" +} + + +Change:: + +Input:: +//// [/users/username/projects/project/tsconfig.json] +{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"preact"}} + + +Output:: +index.tsx:1:31 - error TS2322: Type '{ propA: boolean; }' is not assignable to type '{ propB?: boolean; }'. + Property 'propA' does not exist on type '{ propB?: boolean; }'. Did you mean 'propB'? + +1 export const App = () =>
; +   ~~~~~ + + +Found 1 error. + + + +Program root files: ["/users/username/projects/project/index.tsx"] +Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preact","configFilePath":"/users/username/projects/project/tsconfig.json"} +Program structureReused: Not +Program files:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts + +WatchedFiles:: + +FsWatches:: + +FsWatchesRecursive:: + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated + +//// [/users/username/projects/project/index.js] +"use strict"; +exports.__esModule = true; +exports.App = void 0; +var jsx_runtime_1 = require("preact/jsx-runtime"); +var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); }; +exports.App = App; + + +//// [/users/username/projects/project/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../a/lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false + }, + "./node_modules/preact/jsx-runtime/index.d.ts": { + "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "affectsGlobalScope": false + } + }, + "options": { + "module": 1, + "jsx": 4, + "incremental": true, + "jsxImportSource": "preact", + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": { + "./index.tsx": [ + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../../../a/lib/lib.d.ts", + [ + "./index.tsx", + [ + { + "file": "./index.tsx", + "start": 30, + "length": 5, + "code": 2322, + "category": 1, + "messageText": { + "messageText": "Type '{ propA: boolean; }' is not assignable to type '{ propB?: boolean; }'.", + "category": 1, + "code": 2322, + "next": [ + { + "messageText": "Property 'propA' does not exist on type '{ propB?: boolean; }'. Did you mean 'propB'?", + "category": 1, + "code": 2551 + } + ] + } + } + ] + ], + "./node_modules/preact/jsx-runtime/index.d.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js new file mode 100644 index 0000000000000..49bd165b3b139 --- /dev/null +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js @@ -0,0 +1,285 @@ +Input:: +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts] +export namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { + propA?: boolean; + }; + } +} +export function jsx(...args: any[]): void; +export function jsxs(...args: any[]): void; +export const Fragment: unique symbol; + + +//// [/users/username/projects/project/node_modules/react/package.json] +{"name":"react","version":"0.0.1"} + +//// [/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts] +export namespace JSX { + interface Element {} + interface IntrinsicElements { + div: { + propB?: boolean; + }; + } +} +export function jsx(...args: any[]): void; +export function jsxs(...args: any[]): void; +export const Fragment: unique symbol; + + +//// [/users/username/projects/project/node_modules/preact/package.json] +{"name":"preact","version":"0.0.1"} + +//// [/users/username/projects/project/index.tsx] +export const App = () =>
; + +//// [/users/username/projects/project/tsconfig.json] +{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"react"}} + + +/a/lib/tsc.js -w +Output:: +>> Screen clear +[12:00:39 AM] Starting compilation in watch mode... + +[12:00:44 AM] Found 0 errors. Watching for file changes. + + + +Program root files: ["/users/username/projects/project/index.tsx"] +Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react","watch":true,"configFilePath":"/users/username/projects/project/tsconfig.json"} +Program structureReused: Not +Program files:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts + +WatchedFiles:: +/users/username/projects/project/tsconfig.json: + {"fileName":"/users/username/projects/project/tsconfig.json","pollingInterval":250} +/users/username/projects/project/index.tsx: + {"fileName":"/users/username/projects/project/index.tsx","pollingInterval":250} +/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts: + {"fileName":"/users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts","pollingInterval":250} +/a/lib/lib.d.ts: + {"fileName":"/a/lib/lib.d.ts","pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/users/username/projects/project/node_modules: + {"directoryName":"/users/username/projects/project/node_modules","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/users/username/projects/project/node_modules/@types: + {"directoryName":"/users/username/projects/project/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/users/username/projects/project: + {"directoryName":"/users/username/projects/project","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +//// [/users/username/projects/project/index.js] +"use strict"; +exports.__esModule = true; +exports.App = void 0; +var jsx_runtime_1 = require("react/jsx-runtime"); +var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); }; +exports.App = App; + + +//// [/users/username/projects/project/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../a/lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false + }, + "./node_modules/react/jsx-runtime/index.d.ts": { + "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "affectsGlobalScope": false + } + }, + "options": { + "module": 1, + "jsx": 4, + "incremental": true, + "jsxImportSource": "react", + "watch": true, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": { + "./index.tsx": [ + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../../../a/lib/lib.d.ts", + "./index.tsx", + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "version": "FakeTSVersion" +} + + +Change:: + +Input:: +//// [/users/username/projects/project/tsconfig.json] +{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"preact"}} + + +Output:: +>> Screen clear +[12:00:48 AM] Starting compilation in watch mode... + +index.tsx:1:31 - error TS2322: Type '{ propA: boolean; }' is not assignable to type '{ propB?: boolean; }'. + Property 'propA' does not exist on type '{ propB?: boolean; }'. Did you mean 'propB'? + +1 export const App = () =>
; +   ~~~~~ + +[12:00:55 AM] Found 1 error. Watching for file changes. + + + +Program root files: ["/users/username/projects/project/index.tsx"] +Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preact","watch":true,"configFilePath":"/users/username/projects/project/tsconfig.json"} +Program structureReused: Not +Program files:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/users/username/projects/project/index.tsx +/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts + +WatchedFiles:: +/users/username/projects/project/tsconfig.json: + {"fileName":"/users/username/projects/project/tsconfig.json","pollingInterval":250} +/users/username/projects/project/index.tsx: + {"fileName":"/users/username/projects/project/index.tsx","pollingInterval":250} +/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts: + {"fileName":"/users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts","pollingInterval":250} +/a/lib/lib.d.ts: + {"fileName":"/a/lib/lib.d.ts","pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/users/username/projects/project/node_modules: + {"directoryName":"/users/username/projects/project/node_modules","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/users/username/projects/project/node_modules/@types: + {"directoryName":"/users/username/projects/project/node_modules/@types","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/users/username/projects/project: + {"directoryName":"/users/username/projects/project","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +//// [/users/username/projects/project/index.js] +"use strict"; +exports.__esModule = true; +exports.App = void 0; +var jsx_runtime_1 = require("preact/jsx-runtime"); +var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); }; +exports.App = App; + + +//// [/users/username/projects/project/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../a/lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false + }, + "./node_modules/preact/jsx-runtime/index.d.ts": { + "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", + "affectsGlobalScope": false + } + }, + "options": { + "module": 1, + "jsx": 4, + "incremental": true, + "jsxImportSource": "preact", + "watch": true, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": { + "./index.tsx": [ + "./node_modules/react/jsx-runtime/index.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../../../a/lib/lib.d.ts", + [ + "./index.tsx", + [ + { + "file": "./index.tsx", + "start": 30, + "length": 5, + "code": 2322, + "category": 1, + "messageText": { + "messageText": "Type '{ propA: boolean; }' is not assignable to type '{ propB?: boolean; }'.", + "category": 1, + "code": 2322, + "next": [ + { + "messageText": "Property 'propA' does not exist on type '{ propB?: boolean; }'. Did you mean 'propB'?", + "category": 1, + "code": 2551 + } + ] + } + } + ] + ], + "./node_modules/preact/jsx-runtime/index.d.ts" + ] + }, + "version": "FakeTSVersion" +} + From fe94a2180c4836cfaab18e2fd97e9befee45cc09 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2020 16:16:23 -0700 Subject: [PATCH 4/5] Use same metho as importHelpers to add synthetic import --- src/compiler/moduleNameResolver.ts | 7 +-- src/compiler/program.ts | 57 ++++++++++--------- ...ImportSource-option-changed-incremental.js | 28 ++++----- .../jsxImportSource-option-changed-watch.js | 28 ++++----- 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5928fb564868a..fbd4f57a4a0fb 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -402,10 +402,8 @@ namespace ts { */ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] { // Use explicit type list from tsconfig.json - // jsxImportSource, if present and in use, creates implicit imports - const implicitImport = getJSXRuntimeImport(getJSXImplicitImportBase(options), options); if (options.types) { - return [...options.types, ...(implicitImport ? [implicitImport] : [])]; + return options.types; } // Walk the primary type lookup locations @@ -436,9 +434,6 @@ namespace ts { } } } - if (implicitImport) { - result.push(implicitImport); - } return result; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bc358a425322d..c6efe7c6b76ab 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1494,7 +1494,7 @@ namespace ts { } // try to verify results of module resolution for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) { - const moduleNames = getModuleNames(newSourceFile, options); + const moduleNames = getModuleNames(newSourceFile); const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile); // ensure that module resolution results are still correct const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo); @@ -2201,6 +2201,15 @@ namespace ts { : b.kind === SyntaxKind.StringLiteral && a.text === b.text; } + function createSyntheticImport(text: string, file: SourceFile) { + const externalHelpersModuleReference = factory.createStringLiteral(text); + const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); + addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); + setParent(externalHelpersModuleReference, importDecl); + setParent(importDecl, file); + return externalHelpersModuleReference; + } + function collectExternalModuleReferences(file: SourceFile): void { if (file.imports) { return; @@ -2216,16 +2225,18 @@ namespace ts { // If we are importing helpers, we need to add a synthetic reference to resolve the // helpers library. - if (options.importHelpers - && (options.isolatedModules || isExternalModuleFile) + if ((options.isolatedModules || isExternalModuleFile) && !file.isDeclarationFile) { - // synthesize 'import "tslib"' declaration - const externalHelpersModuleReference = factory.createStringLiteral(externalHelpersModuleNameText); - const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); - addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); - setParent(externalHelpersModuleReference, importDecl); - setParent(importDecl, file); - imports = [externalHelpersModuleReference]; + if (options.importHelpers) { + // synthesize 'import "tslib"' declaration + imports = [createSyntheticImport(externalHelpersModuleNameText, file)]; + } + const jsxImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); + if (jsxImport) { + // synthesize `import "base/jsx-runtime"` declaration + imports ||= []; + imports.push(createSyntheticImport(jsxImport, file)); + } } for (const node of file.statements) { @@ -2840,16 +2851,11 @@ namespace ts { if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--; } else { - // Don't issue an error when auto-inclusion lookup fails for the jsxImportSource (at this point) - // It may be provided by an ambient module in the compilation, instead. - // A usage of a JSX tag later should report that the module couldn't be resolved if it is not supplied. - if (refFile || typeReferenceDirective !== getJSXRuntimeImport(getJSXImplicitImportBase(options), options)) { - fileProcessingDiagnostics.add(createRefFileDiagnostic( - refFile, - Diagnostics.Cannot_find_type_definition_file_for_0, - typeReferenceDirective - )); - } + fileProcessingDiagnostics.add(createRefFileDiagnostic( + refFile, + Diagnostics.Cannot_find_type_definition_file_for_0, + typeReferenceDirective + )); } if (saveResolution) { @@ -2896,9 +2902,9 @@ namespace ts { function processImportedModules(file: SourceFile) { collectExternalModuleReferences(file); - if (file.imports.length || file.moduleAugmentations.length || getJSXImplicitImportBase(options, file)) { + if (file.imports.length || file.moduleAugmentations.length) { // Because global augmentation doesn't have string literal name, we can check for global augmentation as such. - const moduleNames = getModuleNames(file, options); + const moduleNames = getModuleNames(file); const resolutions = resolveModuleNamesReusingOldState(moduleNames, file); Debug.assert(resolutions.length === moduleNames.length); for (let i = 0; i < moduleNames.length; i++) { @@ -3887,8 +3893,7 @@ namespace ts { } } - function getModuleNames(file: SourceFile, options: CompilerOptions): string[] { - const { imports, moduleAugmentations } = file; + function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] { const res = imports.map(i => i.text); for (const aug of moduleAugmentations) { if (aug.kind === SyntaxKind.StringLiteral) { @@ -3896,10 +3901,6 @@ namespace ts { } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. } - const jsxRuntimeImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); - if (jsxRuntimeImport) { - res.push(jsxRuntimeImport); - } return res; } } diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js index e75b1813ec968..c4b9e292b480f 100644 --- a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js @@ -64,13 +64,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: @@ -98,15 +98,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/react/jsx-runtime/index.d.ts": { "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { @@ -156,13 +156,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preac Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: @@ -190,15 +190,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/preact/jsx-runtime/index.d.ts": { "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js index 49bd165b3b139..9a2d68b431e0d 100644 --- a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js @@ -69,13 +69,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: /users/username/projects/project/tsconfig.json: @@ -117,15 +117,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/react/jsx-runtime/index.d.ts": { "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { @@ -178,13 +178,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preac Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: /users/username/projects/project/tsconfig.json: @@ -226,15 +226,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/preact/jsx-runtime/index.d.ts": { "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { From 1e1ae3034b8dd5e1b222ebdd25c4001f04aeb04e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2020 16:21:36 -0700 Subject: [PATCH 5/5] Update src/compiler/program.ts Co-authored-by: Sheetal Nandi --- src/compiler/program.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c6efe7c6b76ab..c8382594c4c7b 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2234,8 +2234,7 @@ namespace ts { const jsxImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); if (jsxImport) { // synthesize `import "base/jsx-runtime"` declaration - imports ||= []; - imports.push(createSyntheticImport(jsxImport, file)); + (imports ||= []).push(createSyntheticImport(jsxImport, file)); } }