mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Do not always instantiate jsx signatures (#21108)
This commit is contained in:
parent
c0bdd12c4c
commit
c9ef52b9d8
@ -15162,7 +15162,7 @@ namespace ts {
|
||||
* element is not a class element, or the class element type cannot be determined, returns 'undefined'.
|
||||
* For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
|
||||
*/
|
||||
function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type) {
|
||||
function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type | undefined) {
|
||||
Debug.assert(!(valueType.flags & TypeFlags.Union));
|
||||
if (isTypeAny(valueType)) {
|
||||
// Short-circuit if the class tag is using an element type 'any'
|
||||
@ -15181,20 +15181,27 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const instantiatedSignatures = [];
|
||||
for (const signature of signatures) {
|
||||
if (signature.typeParameters) {
|
||||
const isJavascript = isInJavaScriptFile(node);
|
||||
const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0);
|
||||
const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext);
|
||||
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
|
||||
if (sourceAttributesType) {
|
||||
// Instantiate in context of source type
|
||||
const instantiatedSignatures = [];
|
||||
for (const signature of signatures) {
|
||||
if (signature.typeParameters) {
|
||||
const isJavascript = isInJavaScriptFile(node);
|
||||
const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0);
|
||||
const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext);
|
||||
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
|
||||
}
|
||||
else {
|
||||
instantiatedSignatures.push(signature);
|
||||
}
|
||||
}
|
||||
else {
|
||||
instantiatedSignatures.push(signature);
|
||||
}
|
||||
}
|
||||
|
||||
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
else {
|
||||
// Do not instantiate if no source type is provided - type parameters and their constraints will be used by contextual typing
|
||||
return getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15418,7 +15425,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get the element instance type (the result of newing or invoking this tag)
|
||||
const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType || emptyObjectType);
|
||||
const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType);
|
||||
|
||||
// If we should include all stateless attributes type, then get all attributes type from all stateless function signature.
|
||||
// Otherwise get only attributes type from the signature picked by choose-overload logic.
|
||||
|
||||
32
tests/baselines/reference/jsxHasLiteralType.js
Normal file
32
tests/baselines/reference/jsxHasLiteralType.js
Normal file
@ -0,0 +1,32 @@
|
||||
//// [jsxHasLiteralType.tsx]
|
||||
import * as React from "react";
|
||||
|
||||
interface Props {
|
||||
x?: "a" | "b";
|
||||
}
|
||||
class MyComponent<P extends Props = Props> extends React.Component<P, {}> {}
|
||||
const m = <MyComponent x="a"/>
|
||||
|
||||
|
||||
//// [jsxHasLiteralType.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var MyComponent = /** @class */ (function (_super) {
|
||||
__extends(MyComponent, _super);
|
||||
function MyComponent() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return MyComponent;
|
||||
}(React.Component));
|
||||
var m = React.createElement(MyComponent, { x: "a" });
|
||||
25
tests/baselines/reference/jsxHasLiteralType.symbols
Normal file
25
tests/baselines/reference/jsxHasLiteralType.symbols
Normal file
@ -0,0 +1,25 @@
|
||||
=== tests/cases/compiler/jsxHasLiteralType.tsx ===
|
||||
import * as React from "react";
|
||||
>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6))
|
||||
|
||||
interface Props {
|
||||
>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31))
|
||||
|
||||
x?: "a" | "b";
|
||||
>x : Symbol(Props.x, Decl(jsxHasLiteralType.tsx, 2, 17))
|
||||
}
|
||||
class MyComponent<P extends Props = Props> extends React.Component<P, {}> {}
|
||||
>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1))
|
||||
>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18))
|
||||
>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31))
|
||||
>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18))
|
||||
|
||||
const m = <MyComponent x="a"/>
|
||||
>m : Symbol(m, Decl(jsxHasLiteralType.tsx, 6, 5))
|
||||
>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1))
|
||||
>x : Symbol(x, Decl(jsxHasLiteralType.tsx, 6, 22))
|
||||
|
||||
26
tests/baselines/reference/jsxHasLiteralType.types
Normal file
26
tests/baselines/reference/jsxHasLiteralType.types
Normal file
@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/jsxHasLiteralType.tsx ===
|
||||
import * as React from "react";
|
||||
>React : typeof React
|
||||
|
||||
interface Props {
|
||||
>Props : Props
|
||||
|
||||
x?: "a" | "b";
|
||||
>x : "a" | "b" | undefined
|
||||
}
|
||||
class MyComponent<P extends Props = Props> extends React.Component<P, {}> {}
|
||||
>MyComponent : MyComponent<P>
|
||||
>P : P
|
||||
>Props : Props
|
||||
>Props : Props
|
||||
>React.Component : React.Component<P, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>P : P
|
||||
|
||||
const m = <MyComponent x="a"/>
|
||||
>m : JSX.Element
|
||||
><MyComponent x="a"/> : JSX.Element
|
||||
>MyComponent : typeof MyComponent
|
||||
>x : "a"
|
||||
|
||||
11
tests/cases/compiler/jsxHasLiteralType.tsx
Normal file
11
tests/cases/compiler/jsxHasLiteralType.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
// @strictNullChecks: true
|
||||
// @jsx: react
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: lib.d.ts,react.d.ts
|
||||
import * as React from "react";
|
||||
|
||||
interface Props {
|
||||
x?: "a" | "b";
|
||||
}
|
||||
class MyComponent<P extends Props = Props> extends React.Component<P, {}> {}
|
||||
const m = <MyComponent x="a"/>
|
||||
Loading…
x
Reference in New Issue
Block a user