Do not always instantiate jsx signatures (#21108)

This commit is contained in:
Wesley Wigham 2018-01-09 17:22:19 -08:00 committed by GitHub
parent c0bdd12c4c
commit c9ef52b9d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 115 additions and 14 deletions

View File

@ -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.

View 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" });

View 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))

View 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"

View 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"/>