diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 7d940cf747ee8..01b93f5800b6d 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -29620,18 +29620,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function getJsxManagedAttributesFromLocatedAttributes(context: JsxOpeningLikeElement, ns: Symbol, attributesType: Type) {
const managedSym = getJsxLibraryManagedAttributes(ns);
if (managedSym) {
- const declaredManagedType = getDeclaredTypeOfSymbol(managedSym); // fetches interface type, or initializes symbol links type parmaeters
const ctorType = getStaticTypeOfReferencedJsxConstructor(context);
- if (managedSym.flags & SymbolFlags.TypeAlias) {
- const params = getSymbolLinks(managedSym).typeParameters;
- if (length(params) >= 2) {
- const args = fillMissingTypeArguments([ctorType, attributesType], params, 2, isInJSFile(context));
- return getTypeAliasInstantiation(managedSym, args);
- }
- }
- if (length((declaredManagedType as GenericType).typeParameters) >= 2) {
- const args = fillMissingTypeArguments([ctorType, attributesType], (declaredManagedType as GenericType).typeParameters, 2, isInJSFile(context));
- return createTypeReference((declaredManagedType as GenericType), args);
+ const result = instantiateAliasOrInterfaceWithDefaults(managedSym, isInJSFile(context), ctorType, attributesType);
+ if (result) {
+ return result;
}
}
return attributesType;
@@ -30690,6 +30682,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return jsxNamespace && getSymbol(jsxNamespace.exports!, JsxNames.LibraryManagedAttributes, SymbolFlags.Type);
}
+ function getJsxElementTypeSymbol(jsxNamespace: Symbol) {
+ // JSX.ElementType [symbol]
+ return jsxNamespace && getSymbol(jsxNamespace.exports!, JsxNames.ElementType, SymbolFlags.Type);
+ }
+
/// e.g. "props" for React.d.ts,
/// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
/// non-intrinsic elements' attributes type is 'any'),
@@ -30826,11 +30823,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getJsxElementTypeTypeAt(location: Node): Type | undefined {
- const type = getJsxType(JsxNames.ElementType, location);
- if (isErrorType(type)) return undefined;
+ const ns = getJsxNamespaceAt(location);
+ if (!ns) return undefined;
+ const sym = getJsxElementTypeSymbol(ns);
+ if (!sym) return undefined;
+ const type = instantiateAliasOrInterfaceWithDefaults(sym, isInJSFile(location));
+ if (!type || isErrorType(type)) return undefined;
return type;
}
+ function instantiateAliasOrInterfaceWithDefaults(managedSym: Symbol, inJs: boolean, ...typeArguments: Type[]) {
+ const declaredManagedType = getDeclaredTypeOfSymbol(managedSym); // fetches interface type, or initializes symbol links type parmaeters
+ if (managedSym.flags & SymbolFlags.TypeAlias) {
+ const params = getSymbolLinks(managedSym).typeParameters;
+ if (length(params) >= typeArguments.length) {
+ const args = fillMissingTypeArguments(typeArguments, params, typeArguments.length, inJs);
+ return length(args) === 0 ? declaredManagedType : getTypeAliasInstantiation(managedSym, args);
+ }
+ }
+ if (length((declaredManagedType as GenericType).typeParameters) >= typeArguments.length) {
+ const args = fillMissingTypeArguments(typeArguments, (declaredManagedType as GenericType).typeParameters, typeArguments.length, inJs);
+ return createTypeReference((declaredManagedType as GenericType), args);
+ }
+ return undefined;
+ }
+
/**
* Returns all the properties of the Jsx.IntrinsicElements interface
*/
diff --git a/tests/baselines/reference/jsxElementTypeLiteralWithGeneric.errors.txt b/tests/baselines/reference/jsxElementTypeLiteralWithGeneric.errors.txt
new file mode 100644
index 0000000000000..b710331de39d9
--- /dev/null
+++ b/tests/baselines/reference/jsxElementTypeLiteralWithGeneric.errors.txt
@@ -0,0 +1,33 @@
+tests/cases/compiler/jsxElementTypeLiteralWithGeneric.tsx(21,9): error TS2339: Property 'ruhroh' does not exist on type 'JSX.IntrinsicElements'.
+tests/cases/compiler/jsxElementTypeLiteralWithGeneric.tsx(21,10): error TS2786: 'ruhroh' cannot be used as a JSX component.
+ Its type '"ruhroh"' is not a valid JSX element type.
+
+
+==== tests/cases/compiler/jsxElementTypeLiteralWithGeneric.tsx (2 errors) ====
+ ///
= + | { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] + ? K + : never; + }[keyof JSX.IntrinsicElements] + | React.ComponentType
; + } + } + + // should be fine - `ElementType` accepts `div` + let a =
; + + // Should be an error. + // `ruhroh` is in neither `IntrinsicElements` nor `ElementType` + let c == + | { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] + ? K + : never; + }[keyof JSX.IntrinsicElements] + | React.ComponentType
; + } +} + +// should be fine - `ElementType` accepts `div` +let a =
; + +// Should be an error. +// `ruhroh` is in neither `IntrinsicElements` nor `ElementType` +let c == +>ElementType : Symbol(ElementType, Decl(jsxElementTypeLiteralWithGeneric.tsx, 4, 17)) +>P : Symbol(P, Decl(jsxElementTypeLiteralWithGeneric.tsx, 5, 21)) + + | { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] +>K : Symbol(K, Decl(jsxElementTypeLiteralWithGeneric.tsx, 7, 9)) +>JSX : Symbol(JSX, Decl(react16.d.ts, 2493, 12), Decl(jsxElementTypeLiteralWithGeneric.tsx, 3, 16)) +>IntrinsicElements : Symbol(IntrinsicElements, Decl(react16.d.ts, 2514, 86)) +>P : Symbol(P, Decl(jsxElementTypeLiteralWithGeneric.tsx, 5, 21)) +>JSX : Symbol(JSX, Decl(react16.d.ts, 2493, 12), Decl(jsxElementTypeLiteralWithGeneric.tsx, 3, 16)) +>IntrinsicElements : Symbol(IntrinsicElements, Decl(react16.d.ts, 2514, 86)) +>K : Symbol(K, Decl(jsxElementTypeLiteralWithGeneric.tsx, 7, 9)) + + ? K +>K : Symbol(K, Decl(jsxElementTypeLiteralWithGeneric.tsx, 7, 9)) + + : never; + }[keyof JSX.IntrinsicElements] +>JSX : Symbol(JSX, Decl(react16.d.ts, 2493, 12), Decl(jsxElementTypeLiteralWithGeneric.tsx, 3, 16)) +>IntrinsicElements : Symbol(IntrinsicElements, Decl(react16.d.ts, 2514, 86)) + + | React.ComponentType
; +>React : Symbol(React, Decl(jsxElementTypeLiteralWithGeneric.tsx, 1, 6)) +>ComponentType : Symbol(React.ComponentType, Decl(react16.d.ts, 117, 60)) +>P : Symbol(P, Decl(jsxElementTypeLiteralWithGeneric.tsx, 5, 21)) + } +} + +// should be fine - `ElementType` accepts `div` +let a =
; +>a : Symbol(a, Decl(jsxElementTypeLiteralWithGeneric.tsx, 16, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) + +// Should be an error. +// `ruhroh` is in neither `IntrinsicElements` nor `ElementType` +let c == +>ElementType : ElementType
+ + | { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] +>JSX : any +>JSX : any + + ? K + : never; + }[keyof JSX.IntrinsicElements] +>JSX : any + + | React.ComponentType
; +>React : any + } +} + +// should be fine - `ElementType` accepts `div` +let a =
; +>a : JSX.Element +> : JSX.Element +>div : any + +// Should be an error. +// `ruhroh` is in neither `IntrinsicElements` nor `ElementType` +let c == + | { + [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] + ? K + : never; + }[keyof JSX.IntrinsicElements] + | React.ComponentType
; + } +} + +// should be fine - `ElementType` accepts `div` +let a =
; + +// Should be an error. +// `ruhroh` is in neither `IntrinsicElements` nor `ElementType` +let c =