mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
Parse and check type arguments on JSX opening and self-closing tags (#22415)
* Parse and check type arguments on JSX opening like elements * Fix nits
This commit is contained in:
@@ -14660,7 +14660,7 @@ namespace ts {
|
||||
return mapType(valueType, t => getJsxSignaturesParameterTypes(t, isJs, node));
|
||||
}
|
||||
|
||||
function getJsxSignaturesParameterTypes(valueType: Type, isJs: boolean, context: Node) {
|
||||
function getJsxSignaturesParameterTypes(valueType: Type, isJs: boolean, context: JsxOpeningLikeElement) {
|
||||
// If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type
|
||||
if (valueType.flags & TypeFlags.String) {
|
||||
return anyType;
|
||||
@@ -14698,6 +14698,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (context.typeArguments) {
|
||||
signatures = mapDefined(signatures, s => getJsxSignatureTypeArgumentInstantiation(s, context, isJs));
|
||||
}
|
||||
|
||||
return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromConstructSignature(t, isJs, context) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None);
|
||||
}
|
||||
|
||||
@@ -15508,21 +15512,57 @@ namespace ts {
|
||||
|
||||
// Instantiate in context of source type
|
||||
const instantiatedSignatures = [];
|
||||
let candidateForTypeArgumentError: Signature;
|
||||
let hasTypeArgumentError: boolean = !!node.typeArguments;
|
||||
for (const signature of signatures) {
|
||||
if (signature.typeParameters) {
|
||||
const isJavascript = isInJavaScriptFile(node);
|
||||
const inferenceContext = createInferenceContext(signature.typeParameters, signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
const typeArguments = inferJsxTypeArguments(signature, node, inferenceContext);
|
||||
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
|
||||
const typeArgumentInstantiated = getJsxSignatureTypeArgumentInstantiation(signature, node, isJavascript, /*reportErrors*/ false);
|
||||
if (typeArgumentInstantiated) {
|
||||
hasTypeArgumentError = false;
|
||||
instantiatedSignatures.push(typeArgumentInstantiated);
|
||||
}
|
||||
else {
|
||||
if (node.typeArguments && hasCorrectTypeArgumentArity(signature, node.typeArguments)) {
|
||||
candidateForTypeArgumentError = signature;
|
||||
}
|
||||
const inferenceContext = createInferenceContext(signature.typeParameters, signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
const typeArguments = inferJsxTypeArguments(signature, node, inferenceContext);
|
||||
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
|
||||
}
|
||||
}
|
||||
else {
|
||||
instantiatedSignatures.push(signature);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.typeArguments && hasTypeArgumentError) {
|
||||
if (candidateForTypeArgumentError) {
|
||||
checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true);
|
||||
}
|
||||
// Length check to avoid issuing an arity error on length=0, the "Type argument list cannot be empty" grammar error alone is fine
|
||||
else if (node.typeArguments.length !== 0) {
|
||||
diagnostics.add(getTypeArgumentArityError(node, signatures, node.typeArguments));
|
||||
}
|
||||
}
|
||||
|
||||
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
function getJsxSignatureTypeArgumentInstantiation(signature: Signature, node: JsxOpeningLikeElement, isJavascript: boolean, reportErrors?: boolean) {
|
||||
if (!node.typeArguments) {
|
||||
return;
|
||||
}
|
||||
if (!hasCorrectTypeArgumentArity(signature, node.typeArguments)) {
|
||||
return;
|
||||
}
|
||||
const args = checkTypeArguments(signature, node.typeArguments, reportErrors);
|
||||
if (!args) {
|
||||
return;
|
||||
}
|
||||
return getSignatureInstantiation(signature, args, isJavascript);
|
||||
}
|
||||
|
||||
function getJsxNamespaceAt(location: Node) {
|
||||
const namespaceName = getJsxNamespace(location);
|
||||
const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
|
||||
@@ -16784,13 +16824,7 @@ namespace ts {
|
||||
spreadArgIndex = getSpreadArgumentIndex(args);
|
||||
}
|
||||
|
||||
// If the user supplied type arguments, but the number of type arguments does not match
|
||||
// the declared number of type parameters, the call has an incorrect arity.
|
||||
const numTypeParameters = length(signature.typeParameters);
|
||||
const minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
|
||||
const hasRightNumberOfTypeArgs = !typeArguments ||
|
||||
(typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
|
||||
if (!hasRightNumberOfTypeArgs) {
|
||||
if (!hasCorrectTypeArgumentArity(signature, typeArguments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16810,6 +16844,15 @@ namespace ts {
|
||||
return callIsIncomplete || hasEnoughArguments;
|
||||
}
|
||||
|
||||
function hasCorrectTypeArgumentArity(signature: Signature, typeArguments: NodeArray<TypeNode> | undefined) {
|
||||
// If the user supplied type arguments, but the number of type arguments does not match
|
||||
// the declared number of type parameters, the call has an incorrect arity.
|
||||
const numTypeParameters = length(signature.typeParameters);
|
||||
const minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
|
||||
return !typeArguments ||
|
||||
(typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
|
||||
}
|
||||
|
||||
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
|
||||
function getSingleCallSignature(type: Type): Signature {
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
@@ -17371,6 +17414,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeArgumentArityError(node: Node, signatures: Signature[], typeArguments: NodeArray<TypeNode>) {
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const sig of signatures) {
|
||||
min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
|
||||
max = Math.max(max, length(sig.typeParameters));
|
||||
}
|
||||
const paramCount = min === max ? min : min + "-" + max;
|
||||
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length);
|
||||
}
|
||||
|
||||
function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[], fallbackError?: DiagnosticMessage): Signature {
|
||||
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
|
||||
const isDecorator = node.kind === SyntaxKind.Decorator;
|
||||
@@ -17498,14 +17552,7 @@ namespace ts {
|
||||
checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression).typeArguments, /*reportErrors*/ true, fallbackError);
|
||||
}
|
||||
else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments.length)) {
|
||||
let min = Number.POSITIVE_INFINITY;
|
||||
let max = Number.NEGATIVE_INFINITY;
|
||||
for (const sig of signatures) {
|
||||
min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
|
||||
max = Math.max(max, length(sig.typeParameters));
|
||||
}
|
||||
const paramCount = min < max ? min + "-" + max : min;
|
||||
diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
|
||||
diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments));
|
||||
}
|
||||
else if (args) {
|
||||
let min = Number.POSITIVE_INFINITY;
|
||||
@@ -26722,6 +26769,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
|
||||
checkGrammarTypeArguments(node, node.typeArguments);
|
||||
const seen = createUnderscoreEscapedMap<boolean>();
|
||||
|
||||
for (const attr of node.attributes.properties) {
|
||||
|
||||
@@ -2160,31 +2160,35 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes) {
|
||||
const node = <JsxSelfClosingElement>createSynthesizedNode(SyntaxKind.JsxSelfClosingElement);
|
||||
node.tagName = tagName;
|
||||
node.typeArguments = typeArguments && createNodeArray(typeArguments);
|
||||
node.attributes = attributes;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes) {
|
||||
return node.tagName !== tagName
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.attributes !== attributes
|
||||
? updateNode(createJsxSelfClosingElement(tagName, attributes), node)
|
||||
? updateNode(createJsxSelfClosingElement(tagName, typeArguments, attributes), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
export function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes) {
|
||||
const node = <JsxOpeningElement>createSynthesizedNode(SyntaxKind.JsxOpeningElement);
|
||||
node.tagName = tagName;
|
||||
node.typeArguments = typeArguments && createNodeArray(typeArguments);
|
||||
node.attributes = attributes;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes) {
|
||||
return node.tagName !== tagName
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.attributes !== attributes
|
||||
? updateNode(createJsxOpeningElement(tagName, attributes), node)
|
||||
? updateNode(createJsxOpeningElement(tagName, typeArguments, attributes), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
||||
@@ -429,6 +429,7 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
|
||||
visitNodes(cbNode, cbNodes, (<JsxOpeningLikeElement>node).typeArguments) ||
|
||||
visitNode(cbNode, (<JsxOpeningLikeElement>node).attributes);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return visitNodes(cbNode, cbNodes, (<JsxAttributes>node).properties);
|
||||
@@ -4197,6 +4198,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const tagName = parseJsxElementName();
|
||||
const typeArguments = tryParseTypeArguments();
|
||||
const attributes = parseJsxAttributes();
|
||||
|
||||
let node: JsxOpeningLikeElement;
|
||||
@@ -4221,6 +4223,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
node.tagName = tagName;
|
||||
node.typeArguments = typeArguments;
|
||||
node.attributes = attributes;
|
||||
|
||||
return finishNode(node);
|
||||
|
||||
@@ -1458,8 +1458,10 @@ namespace ts {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
// Check type arguments
|
||||
if (nodes === (<CallExpression | NewExpression | ExpressionWithTypeArguments>parent).typeArguments) {
|
||||
if (nodes === (<CallExpression | NewExpression | ExpressionWithTypeArguments | JsxOpeningLikeElement>parent).typeArguments) {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1768,6 +1768,7 @@ namespace ts {
|
||||
kind: SyntaxKind.JsxOpeningElement;
|
||||
parent?: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
@@ -1775,6 +1776,7 @@ namespace ts {
|
||||
export interface JsxSelfClosingElement extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxSelfClosingElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
|
||||
@@ -821,11 +821,13 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return updateJsxSelfClosingElement(<JsxSelfClosingElement>node,
|
||||
visitNode((<JsxSelfClosingElement>node).tagName, visitor, isJsxTagNameExpression),
|
||||
nodesVisitor((<JsxSelfClosingElement>node).typeArguments, visitor, isTypeNode),
|
||||
visitNode((<JsxSelfClosingElement>node).attributes, visitor, isJsxAttributes));
|
||||
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return updateJsxOpeningElement(<JsxOpeningElement>node,
|
||||
visitNode((<JsxOpeningElement>node).tagName, visitor, isJsxTagNameExpression),
|
||||
nodesVisitor((<JsxSelfClosingElement>node).typeArguments, visitor, isTypeNode),
|
||||
visitNode((<JsxOpeningElement>node).attributes, visitor, isJsxAttributes));
|
||||
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
|
||||
@@ -1081,11 +1081,13 @@ declare namespace ts {
|
||||
kind: SyntaxKind.JsxOpeningElement;
|
||||
parent?: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxSelfClosingElement extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxSelfClosingElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxFragment extends PrimaryExpression {
|
||||
@@ -3675,10 +3677,10 @@ declare namespace ts {
|
||||
function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference;
|
||||
function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement): JsxElement;
|
||||
function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement): JsxElement;
|
||||
function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
|
||||
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
|
||||
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
|
||||
|
||||
10
tests/baselines/reference/api/typescript.d.ts
vendored
10
tests/baselines/reference/api/typescript.d.ts
vendored
@@ -1081,11 +1081,13 @@ declare namespace ts {
|
||||
kind: SyntaxKind.JsxOpeningElement;
|
||||
parent?: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxSelfClosingElement extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxSelfClosingElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxFragment extends PrimaryExpression {
|
||||
@@ -3622,10 +3624,10 @@ declare namespace ts {
|
||||
function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference;
|
||||
function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement): JsxElement;
|
||||
function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement): JsxElement;
|
||||
function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxSelfClosingElement;
|
||||
function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray<TypeNode> | undefined, attributes: JsxAttributes): JsxOpeningElement;
|
||||
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
|
||||
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
|
||||
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
tests/cases/conformance/jsx/file.jsx(4,17): error TS8011: 'type arguments' can only be used in a .ts file.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/component.d.ts (0 errors) ====
|
||||
import * as React from "react";
|
||||
export declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
export interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
==== tests/cases/conformance/jsx/file.jsx (1 errors) ====
|
||||
import { MyComp, Prop } from "./component";
|
||||
import * as React from "react";
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
~~~~
|
||||
!!! error TS8011: 'type arguments' can only be used in a .ts file.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//// [tests/cases/conformance/jsx/jsxCheckJsxNoTypeArgumentsAllowed.tsx] ////
|
||||
|
||||
//// [component.d.ts]
|
||||
import * as React from "react";
|
||||
export declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
export interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
import { MyComp, Prop } from "./component";
|
||||
import * as React from "react";
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var component_1 = require("./component");
|
||||
var React = require("react");
|
||||
var x = <component_1.MyComp a={10} b="hi"/>; // error, no type arguments in js
|
||||
@@ -0,0 +1,42 @@
|
||||
=== tests/cases/conformance/jsx/component.d.ts ===
|
||||
import * as React from "react";
|
||||
>React : Symbol(React, Decl(component.d.ts, 0, 6))
|
||||
|
||||
export declare class MyComp<P> extends React.Component<P, {}> {
|
||||
>MyComp : Symbol(MyComp, Decl(component.d.ts, 0, 31))
|
||||
>P : Symbol(P, Decl(component.d.ts, 1, 28))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>React : Symbol(React, Decl(component.d.ts, 0, 6))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>P : Symbol(P, Decl(component.d.ts, 1, 28))
|
||||
|
||||
internalProp: P;
|
||||
>internalProp : Symbol(MyComp.internalProp, Decl(component.d.ts, 1, 63))
|
||||
>P : Symbol(P, Decl(component.d.ts, 1, 28))
|
||||
}
|
||||
|
||||
export interface Prop {
|
||||
>Prop : Symbol(Prop, Decl(component.d.ts, 3, 1))
|
||||
|
||||
a: number,
|
||||
>a : Symbol(Prop.a, Decl(component.d.ts, 5, 23))
|
||||
|
||||
b: string
|
||||
>b : Symbol(Prop.b, Decl(component.d.ts, 6, 14))
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/jsx/file.jsx ===
|
||||
import { MyComp, Prop } from "./component";
|
||||
>MyComp : Symbol(MyComp, Decl(file.jsx, 0, 8))
|
||||
>Prop : Symbol(Prop, Decl(file.jsx, 0, 16))
|
||||
|
||||
import * as React from "react";
|
||||
>React : Symbol(React, Decl(file.jsx, 1, 6))
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
>x : Symbol(x, Decl(file.jsx, 3, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.jsx, 0, 8))
|
||||
>Prop : Symbol(Prop, Decl(file.jsx, 0, 16))
|
||||
>a : Symbol(a, Decl(file.jsx, 3, 21))
|
||||
>b : Symbol(b, Decl(file.jsx, 3, 28))
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
=== tests/cases/conformance/jsx/component.d.ts ===
|
||||
import * as React from "react";
|
||||
>React : typeof React
|
||||
|
||||
export declare class MyComp<P> extends React.Component<P, {}> {
|
||||
>MyComp : MyComp<P>
|
||||
>P : P
|
||||
>React.Component : React.Component<P, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>P : P
|
||||
|
||||
internalProp: P;
|
||||
>internalProp : P
|
||||
>P : P
|
||||
}
|
||||
|
||||
export interface Prop {
|
||||
>Prop : Prop
|
||||
|
||||
a: number,
|
||||
>a : number
|
||||
|
||||
b: string
|
||||
>b : string
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/jsx/file.jsx ===
|
||||
import { MyComp, Prop } from "./component";
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : any
|
||||
|
||||
import * as React from "react";
|
||||
>React : typeof React
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop> a={10} b="hi" /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
|
||||
145
tests/baselines/reference/tsxTypeArgumentResolution.errors.txt
Normal file
145
tests/baselines/reference/tsxTypeArgumentResolution.errors.txt
Normal file
@@ -0,0 +1,145 @@
|
||||
tests/cases/conformance/jsx/file.tsx(16,19): error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp<Prop>> & Prop & { children?: ReactNode; }'.
|
||||
Type '{ a: number; b: number; }' is not assignable to type 'Prop'.
|
||||
Types of property 'b' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(18,19): error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp<Prop>> & Prop & { children?: ReactNode; }'.
|
||||
Type '{ a: number; b: number; }' is not assignable to type 'Prop'.
|
||||
Types of property 'b' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(20,13): error TS2558: Expected 1 type arguments, but got 2.
|
||||
tests/cases/conformance/jsx/file.tsx(22,13): error TS2558: Expected 1 type arguments, but got 2.
|
||||
tests/cases/conformance/jsx/file.tsx(24,12): error TS1099: Type argument list cannot be empty.
|
||||
tests/cases/conformance/jsx/file.tsx(26,12): error TS1099: Type argument list cannot be empty.
|
||||
tests/cases/conformance/jsx/file.tsx(39,14): error TS2344: Type 'Prop' does not satisfy the constraint '{ a: string; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(39,20): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
Type '{ a: number; b: string; }' is not assignable to type '{ a: string; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(41,14): error TS2344: Type 'Prop' does not satisfy the constraint '{ a: string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(41,20): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
Type '{ a: number; b: string; }' is not assignable to type '{ a: string; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(47,14): error TS2558: Expected 1-2 type arguments, but got 3.
|
||||
tests/cases/conformance/jsx/file.tsx(47,53): error TS2339: Property 'b' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(49,14): error TS2558: Expected 1-2 type arguments, but got 3.
|
||||
tests/cases/conformance/jsx/file.tsx(49,53): error TS2339: Property 'b' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(51,40): error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, { b: number; }>> & { a: string; } & { b: number; } & { children?: ReactNode; }'.
|
||||
Type '{ a: string; b: string; }' is not assignable to type '{ b: number; }'.
|
||||
Types of property 'b' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsx/file.tsx(53,40): error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, { b: number; }>> & { a: string; } & { b: number; } & { children?: ReactNode; }'.
|
||||
Type '{ a: string; b: string; }' is not assignable to type '{ b: number; }'.
|
||||
Types of property 'b' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (16 errors) ====
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b="hi"></MyComp>; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20} />; // error
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp<Prop>> & Prop & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'Prop'.
|
||||
!!! error TS2322: Types of property 'b' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20}></MyComp>; // error
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp<Prop>> & Prop & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'Prop'.
|
||||
!!! error TS2322: Types of property 'b' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi" />; // error
|
||||
~~~~~~~~~~
|
||||
!!! error TS2558: Expected 1 type arguments, but got 2.
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp>; // error
|
||||
~~~~~~~~~~
|
||||
!!! error TS2558: Expected 1 type arguments, but got 2.
|
||||
|
||||
x = <MyComp<> a={10} b="hi" />; // error
|
||||
~~
|
||||
!!! error TS1099: Type argument list cannot be empty.
|
||||
|
||||
x = <MyComp<> a={10} b="hi"></MyComp>; // error
|
||||
~~
|
||||
!!! error TS1099: Type argument list cannot be empty.
|
||||
|
||||
x= <MyComp<{}> /> // OK
|
||||
|
||||
x= <MyComp<{}>></MyComp> // OK
|
||||
|
||||
declare class MyComp2<P extends { a: string }, P2 = {}> extends React.Component<P & P2, {}> {
|
||||
internalProp: [P, P2];
|
||||
}
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi" />; // error
|
||||
~~~~
|
||||
!!! error TS2344: Type 'Prop' does not satisfy the constraint '{ a: string; }'.
|
||||
!!! error TS2344: Types of property 'a' are incompatible.
|
||||
!!! error TS2344: Type 'number' is not assignable to type 'string'.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type '{ a: string; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi"></MyComp2>; // error
|
||||
~~~~
|
||||
!!! error TS2344: Type 'Prop' does not satisfy the constraint '{ a: string; }'.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: number; b: string; }' is not assignable to type '{ a: string; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" />; // error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 1-2 type arguments, but got 3.
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2>; // error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 1-2 type arguments, but got 3.
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, {}>> & { a: string; } & { children?: ReactNode; }'.
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" />; // error
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, { b: number; }>> & { a: string; } & { b: number; } & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type '{ b: number; }'.
|
||||
!!! error TS2322: Types of property 'b' are incompatible.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2>; // error
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<MyComp2<{ a: string; }, { b: number; }>> & { a: string; } & { b: number; } & { children?: ReactNode; }'.
|
||||
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type '{ b: number; }'.
|
||||
!!! error TS2322: Types of property 'b' are incompatible.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
|
||||
80
tests/baselines/reference/tsxTypeArgumentResolution.js
Normal file
80
tests/baselines/reference/tsxTypeArgumentResolution.js
Normal file
@@ -0,0 +1,80 @@
|
||||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b="hi"></MyComp>; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20} />; // error
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20}></MyComp>; // error
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp>; // error
|
||||
|
||||
x = <MyComp<> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp<> a={10} b="hi"></MyComp>; // error
|
||||
|
||||
x= <MyComp<{}> /> // OK
|
||||
|
||||
x= <MyComp<{}>></MyComp> // OK
|
||||
|
||||
declare class MyComp2<P extends { a: string }, P2 = {}> extends React.Component<P & P2, {}> {
|
||||
internalProp: [P, P2];
|
||||
}
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi"></MyComp2>; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" />; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2>; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" />; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2>; // error
|
||||
|
||||
|
||||
//// [file.jsx]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var React = require("react");
|
||||
var x = <MyComp a={10} b="hi"/>; // OK
|
||||
x = <MyComp a={10} b="hi"></MyComp>; // OK
|
||||
x = <MyComp a={10} b={20}/>; // error
|
||||
x = <MyComp a={10} b={20}></MyComp>; // error
|
||||
x = <MyComp a={10} b="hi"/>; // error
|
||||
x = <MyComp a={10} b="hi"></MyComp>; // error
|
||||
x = <MyComp a={10} b="hi"/>; // error
|
||||
x = <MyComp a={10} b="hi"></MyComp>; // error
|
||||
x = <MyComp />; // OK
|
||||
x = <MyComp></MyComp>; // OK
|
||||
x = <MyComp2 a="a" b="b"/>; // OK
|
||||
x = <MyComp2 a="a" b="b"></MyComp2>; // OK
|
||||
x = <MyComp2 a={10} b="hi"/>; // error
|
||||
x = <MyComp2 a={10} b="hi"></MyComp2>; // error
|
||||
x = <MyComp2 a="hi" b="hi"/>; // OK
|
||||
x = <MyComp2 a="hi" b="hi"></MyComp2>; // OK
|
||||
x = <MyComp2 a="hi" b="hi"/>; // error
|
||||
x = <MyComp2 a="hi" b="hi"></MyComp2>; // error
|
||||
x = <MyComp2 a="hi" b="hi"/>; // error
|
||||
x = <MyComp2 a="hi" b="hi"></MyComp2>; // error
|
||||
197
tests/baselines/reference/tsxTypeArgumentResolution.symbols
Normal file
197
tests/baselines/reference/tsxTypeArgumentResolution.symbols
Normal file
@@ -0,0 +1,197 @@
|
||||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
|
||||
interface Prop {
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
|
||||
a: number,
|
||||
>a : Symbol(Prop.a, Decl(file.tsx, 2, 16))
|
||||
|
||||
b: string
|
||||
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
|
||||
}
|
||||
|
||||
declare class MyComp<P> extends React.Component<P, {}> {
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>P : Symbol(P, Decl(file.tsx, 7, 21))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>P : Symbol(P, Decl(file.tsx, 7, 21))
|
||||
|
||||
internalProp: P;
|
||||
>internalProp : Symbol(MyComp.internalProp, Decl(file.tsx, 7, 56))
|
||||
>P : Symbol(P, Decl(file.tsx, 7, 21))
|
||||
}
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 11, 21))
|
||||
>b : Symbol(b, Decl(file.tsx, 11, 28))
|
||||
|
||||
x = <MyComp<Prop> a={10} b="hi"></MyComp>; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 13, 17))
|
||||
>b : Symbol(b, Decl(file.tsx, 13, 24))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20} />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 15, 17))
|
||||
>b : Symbol(b, Decl(file.tsx, 15, 24))
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20}></MyComp>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 17, 17))
|
||||
>b : Symbol(b, Decl(file.tsx, 17, 24))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi" />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 19, 23))
|
||||
>b : Symbol(b, Decl(file.tsx, 19, 30))
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 21, 23))
|
||||
>b : Symbol(b, Decl(file.tsx, 21, 30))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
x = <MyComp<> a={10} b="hi" />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 23, 13))
|
||||
>b : Symbol(b, Decl(file.tsx, 23, 20))
|
||||
|
||||
x = <MyComp<> a={10} b="hi"></MyComp>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 25, 13))
|
||||
>b : Symbol(b, Decl(file.tsx, 25, 20))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
x= <MyComp<{}> /> // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
x= <MyComp<{}>></MyComp> // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
>MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1))
|
||||
|
||||
declare class MyComp2<P extends { a: string }, P2 = {}> extends React.Component<P & P2, {}> {
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>P : Symbol(P, Decl(file.tsx, 31, 22))
|
||||
>a : Symbol(a, Decl(file.tsx, 31, 33))
|
||||
>P2 : Symbol(P2, Decl(file.tsx, 31, 46))
|
||||
>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>React : Symbol(React, Decl(file.tsx, 0, 0))
|
||||
>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66))
|
||||
>P : Symbol(P, Decl(file.tsx, 31, 22))
|
||||
>P2 : Symbol(P2, Decl(file.tsx, 31, 46))
|
||||
|
||||
internalProp: [P, P2];
|
||||
>internalProp : Symbol(MyComp2.internalProp, Decl(file.tsx, 31, 93))
|
||||
>P : Symbol(P, Decl(file.tsx, 31, 22))
|
||||
>P2 : Symbol(P2, Decl(file.tsx, 31, 46))
|
||||
}
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b" />; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 34, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 34, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 34, 36))
|
||||
>b : Symbol(b, Decl(file.tsx, 34, 42))
|
||||
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2>; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 36, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 36, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 36, 36))
|
||||
>b : Symbol(b, Decl(file.tsx, 36, 42))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi" />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 38, 18))
|
||||
>b : Symbol(b, Decl(file.tsx, 38, 25))
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi"></MyComp2>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 40, 18))
|
||||
>b : Symbol(b, Decl(file.tsx, 40, 25))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" />; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 42, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 42, 27))
|
||||
>a : Symbol(a, Decl(file.tsx, 42, 38))
|
||||
>b : Symbol(b, Decl(file.tsx, 42, 45))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2>; // OK
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 44, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 44, 27))
|
||||
>a : Symbol(a, Decl(file.tsx, 44, 38))
|
||||
>b : Symbol(b, Decl(file.tsx, 44, 45))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 46, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 46, 27))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 46, 44))
|
||||
>b : Symbol(b, Decl(file.tsx, 46, 51))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 48, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 48, 27))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
>a : Symbol(a, Decl(file.tsx, 48, 44))
|
||||
>b : Symbol(b, Decl(file.tsx, 48, 51))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" />; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 50, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 50, 27))
|
||||
>a : Symbol(a, Decl(file.tsx, 50, 38))
|
||||
>b : Symbol(b, Decl(file.tsx, 50, 45))
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2>; // error
|
||||
>x : Symbol(x, Decl(file.tsx, 11, 3))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
>a : Symbol(a, Decl(file.tsx, 52, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 52, 27))
|
||||
>a : Symbol(a, Decl(file.tsx, 52, 38))
|
||||
>b : Symbol(b, Decl(file.tsx, 52, 45))
|
||||
>MyComp2 : Symbol(MyComp2, Decl(file.tsx, 29, 24))
|
||||
|
||||
248
tests/baselines/reference/tsxTypeArgumentResolution.types
Normal file
248
tests/baselines/reference/tsxTypeArgumentResolution.types
Normal file
@@ -0,0 +1,248 @@
|
||||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
import React = require('react');
|
||||
>React : typeof React
|
||||
|
||||
interface Prop {
|
||||
>Prop : Prop
|
||||
|
||||
a: number,
|
||||
>a : number
|
||||
|
||||
b: string
|
||||
>b : string
|
||||
}
|
||||
|
||||
declare class MyComp<P> extends React.Component<P, {}> {
|
||||
>MyComp : MyComp<P>
|
||||
>P : P
|
||||
>React.Component : React.Component<P, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>P : P
|
||||
|
||||
internalProp: P;
|
||||
>internalProp : P
|
||||
>P : P
|
||||
}
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // OK
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop> a={10} b="hi" /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
|
||||
x = <MyComp<Prop> a={10} b="hi"></MyComp>; // OK
|
||||
>x = <MyComp<Prop> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20} />; // error
|
||||
>x = <MyComp<Prop> a={10} b={20} /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop> a={10} b={20} /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : number
|
||||
>20 : 20
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20}></MyComp>; // error
|
||||
>x = <MyComp<Prop> a={10} b={20}></MyComp> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop> a={10} b={20}></MyComp> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : number
|
||||
>20 : 20
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi" />; // error
|
||||
>x = <MyComp<Prop, Prop> a={10} b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop, Prop> a={10} b="hi" /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp>; // error
|
||||
>x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<Prop, Prop> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>Prop : Prop
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
x = <MyComp<> a={10} b="hi" />; // error
|
||||
>x = <MyComp<> a={10} b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<> a={10} b="hi" /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
|
||||
x = <MyComp<> a={10} b="hi"></MyComp>; // error
|
||||
>x = <MyComp<> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<> a={10} b="hi"></MyComp> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
x= <MyComp<{}> /> // OK
|
||||
>x= <MyComp<{}> /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<{}> /> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
x= <MyComp<{}>></MyComp> // OK
|
||||
>x= <MyComp<{}>></MyComp> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp<{}>></MyComp> : JSX.Element
|
||||
>MyComp : typeof MyComp
|
||||
>MyComp : typeof MyComp
|
||||
|
||||
declare class MyComp2<P extends { a: string }, P2 = {}> extends React.Component<P & P2, {}> {
|
||||
>MyComp2 : MyComp2<P, P2>
|
||||
>P : P
|
||||
>a : string
|
||||
>P2 : P2
|
||||
>React.Component : React.Component<P & P2, {}>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>P : P
|
||||
>P2 : P2
|
||||
|
||||
internalProp: [P, P2];
|
||||
>internalProp : [P, P2]
|
||||
>P : P
|
||||
>P2 : P2
|
||||
}
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b" />; // OK
|
||||
>x = <MyComp2<{a: string, b: string}> a="a" b="b" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string, b: string}> a="a" b="b" /> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>a : string
|
||||
>b : string
|
||||
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2>; // OK
|
||||
>x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>a : string
|
||||
>b : string
|
||||
>MyComp2 : typeof MyComp2
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi" />; // error
|
||||
>x = <MyComp2<Prop> a={10} b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<Prop> a={10} b="hi" /> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi"></MyComp2>; // error
|
||||
>x = <MyComp2<Prop> a={10} b="hi"></MyComp2> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<Prop> a={10} b="hi"></MyComp2> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>Prop : Prop
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
>MyComp2 : typeof MyComp2
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" />; // OK
|
||||
>x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: string}> a="hi" b="hi" /> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>a : string
|
||||
>b : string
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2>; // OK
|
||||
>x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>a : string
|
||||
>b : string
|
||||
>MyComp2 : typeof MyComp2
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" />; // error
|
||||
>x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" /> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>Prop : Prop
|
||||
>a : string
|
||||
>b : string
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2>; // error
|
||||
>x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : string
|
||||
>Prop : Prop
|
||||
>a : string
|
||||
>b : string
|
||||
>MyComp2 : typeof MyComp2
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" />; // error
|
||||
>x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" /> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: number}> a="hi" b="hi" /> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : number
|
||||
>a : string
|
||||
>b : string
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2>; // error
|
||||
>x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>x : JSX.Element
|
||||
><MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2> : JSX.Element
|
||||
>MyComp2 : typeof MyComp2
|
||||
>a : string
|
||||
>b : number
|
||||
>a : string
|
||||
>b : string
|
||||
>MyComp2 : typeof MyComp2
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
// @allowJs: true
|
||||
// @outDir: ./out
|
||||
// @checkJs: true
|
||||
// @filename: component.d.ts
|
||||
import * as React from "react";
|
||||
export declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
export interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
// @filename: file.jsx
|
||||
import { MyComp, Prop } from "./component";
|
||||
import * as React from "react";
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
|
||||
59
tests/cases/conformance/jsx/tsxTypeArgumentResolution.tsx
Normal file
59
tests/cases/conformance/jsx/tsxTypeArgumentResolution.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string
|
||||
}
|
||||
|
||||
declare class MyComp<P> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
let x = <MyComp<Prop> a={10} b="hi" />; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b="hi"></MyComp>; // OK
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20} />; // error
|
||||
|
||||
x = <MyComp<Prop> a={10} b={20}></MyComp>; // error
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp<Prop, Prop> a={10} b="hi"></MyComp>; // error
|
||||
|
||||
x = <MyComp<> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp<> a={10} b="hi"></MyComp>; // error
|
||||
|
||||
x= <MyComp<{}> /> // OK
|
||||
|
||||
x= <MyComp<{}>></MyComp> // OK
|
||||
|
||||
declare class MyComp2<P extends { a: string }, P2 = {}> extends React.Component<P & P2, {}> {
|
||||
internalProp: [P, P2];
|
||||
}
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string, b: string}> a="a" b="b"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi" />; // error
|
||||
|
||||
x = <MyComp2<Prop> a={10} b="hi"></MyComp2>; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi" />; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}> a="hi" b="hi"></MyComp2>; // OK
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi" />; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: string}, Prop> a="hi" b="hi"></MyComp2>; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi" />; // error
|
||||
|
||||
x = <MyComp2<{a: string}, {b: number}> a="hi" b="hi"></MyComp2>; // error
|
||||
Reference in New Issue
Block a user