Merge pull request #19249 from uniqueiniquity/jsxFragment
Add support for JSX fragment syntax
This commit is contained in:
commit
7dfd6c7e20
|
@ -3296,6 +3296,9 @@ namespace ts {
|
|||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxText:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.JsxOpeningFragment:
|
||||
case SyntaxKind.JsxClosingFragment:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
|
|
|
@ -13597,7 +13597,13 @@ namespace ts {
|
|||
// JSX expression can appear in two position : JSX Element's children or JSX attribute
|
||||
const jsxAttributes = isJsxAttributeLike(node.parent) ?
|
||||
node.parent.parent :
|
||||
node.parent.openingElement.attributes; // node.parent is JsxElement
|
||||
isJsxElement(node.parent) ?
|
||||
node.parent.openingElement.attributes :
|
||||
undefined; // node.parent is JsxFragment with no attributes
|
||||
|
||||
if (!jsxAttributes) {
|
||||
return undefined; // don't check children of a fragment
|
||||
}
|
||||
|
||||
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
|
||||
// which is a type of the parameter of the signature we are trying out.
|
||||
|
@ -14177,13 +14183,13 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type {
|
||||
checkJsxOpeningLikeElement(node);
|
||||
checkJsxOpeningLikeElementOrOpeningFragment(node);
|
||||
return getJsxGlobalElementType() || anyType;
|
||||
}
|
||||
|
||||
function checkJsxElement(node: JsxElement): Type {
|
||||
// Check attributes
|
||||
checkJsxOpeningLikeElement(node.openingElement);
|
||||
checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement);
|
||||
|
||||
// Perform resolution on the closing tag so that rename/go to definition/etc work
|
||||
if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
|
||||
|
@ -14196,6 +14202,16 @@ namespace ts {
|
|||
return getJsxGlobalElementType() || anyType;
|
||||
}
|
||||
|
||||
function checkJsxFragment(node: JsxFragment): Type {
|
||||
checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
|
||||
|
||||
if (compilerOptions.jsx === JsxEmit.React && compilerOptions.jsxFactory) {
|
||||
error(node, Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory);
|
||||
}
|
||||
|
||||
return getJsxGlobalElementType() || anyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
|
||||
*/
|
||||
|
@ -14859,14 +14875,19 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) {
|
||||
checkGrammarJsxElement(node);
|
||||
function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) {
|
||||
const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node);
|
||||
|
||||
if (isNodeOpeningLikeElement) {
|
||||
checkGrammarJsxElement(<JsxOpeningLikeElement>node);
|
||||
}
|
||||
checkJsxPreconditions(node);
|
||||
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
|
||||
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
|
||||
const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
|
||||
const reactNamespace = getJsxNamespace();
|
||||
const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
|
||||
const reactLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
|
||||
const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
|
||||
if (reactSym) {
|
||||
// Mark local symbol as referenced here because it might not have been marked
|
||||
// if jsx emit was not react as there wont be error being emitted
|
||||
|
@ -14878,7 +14899,9 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
checkJsxAttributesAssignableToTagNameAttributes(node);
|
||||
if (isNodeOpeningLikeElement) {
|
||||
checkJsxAttributesAssignableToTagNameAttributes(<JsxOpeningLikeElement>node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18655,6 +18678,8 @@ namespace ts {
|
|||
return checkJsxElement(<JsxElement>node);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
case SyntaxKind.JsxFragment:
|
||||
return checkJsxFragment(<JsxFragment>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return checkJsxAttributes(<JsxAttributes>node, checkMode);
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
|
|
|
@ -3615,6 +3615,18 @@
|
|||
"category": "Error",
|
||||
"code": 17013
|
||||
},
|
||||
"JSX fragment has no corresponding closing tag.": {
|
||||
"category": "Error",
|
||||
"code": 17014
|
||||
},
|
||||
"Expected corresponding closing tag for JSX fragment.": {
|
||||
"category": "Error",
|
||||
"code": 17015
|
||||
},
|
||||
"JSX fragment is not supported when using --jsxFactory": {
|
||||
"category": "Error",
|
||||
"code":17016
|
||||
},
|
||||
|
||||
"Circularity detected while resolving configuration: {0}": {
|
||||
"category": "Error",
|
||||
|
|
|
@ -699,9 +699,11 @@ namespace ts {
|
|||
case SyntaxKind.JsxText:
|
||||
return emitJsxText(<JsxText>node);
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return emitJsxOpeningElement(<JsxOpeningElement>node);
|
||||
case SyntaxKind.JsxOpeningFragment:
|
||||
return emitJsxOpeningElementOrFragment(<JsxOpeningElement>node);
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
return emitJsxClosingElement(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxClosingFragment:
|
||||
return emitJsxClosingElementOrFragment(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return emitJsxAttribute(<JsxAttribute>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
|
@ -836,6 +838,8 @@ namespace ts {
|
|||
return emitJsxElement(<JsxElement>node);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return emitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
case SyntaxKind.JsxFragment:
|
||||
return emitJsxFragment(<JsxFragment>node);
|
||||
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
|
@ -2060,7 +2064,7 @@ namespace ts {
|
|||
|
||||
function emitJsxElement(node: JsxElement) {
|
||||
emit(node.openingElement);
|
||||
emitList(node, node.children, ListFormat.JsxElementChildren);
|
||||
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
|
||||
emit(node.closingElement);
|
||||
}
|
||||
|
||||
|
@ -2075,14 +2079,24 @@ namespace ts {
|
|||
write("/>");
|
||||
}
|
||||
|
||||
function emitJsxOpeningElement(node: JsxOpeningElement) {
|
||||
function emitJsxFragment(node: JsxFragment) {
|
||||
emit(node.openingFragment);
|
||||
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
|
||||
emit(node.closingFragment);
|
||||
}
|
||||
|
||||
function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
writeIfAny(node.attributes.properties, " ");
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
|
||||
if (isJsxOpeningElement(node)) {
|
||||
emitJsxTagName(node.tagName);
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
write(" ");
|
||||
emit(node.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
write(">");
|
||||
}
|
||||
|
||||
|
@ -2090,9 +2104,11 @@ namespace ts {
|
|||
writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
|
||||
}
|
||||
|
||||
function emitJsxClosingElement(node: JsxClosingElement) {
|
||||
function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) {
|
||||
write("</");
|
||||
emitJsxTagName(node.tagName);
|
||||
if (isJsxClosingElement(node)) {
|
||||
emitJsxTagName(node.tagName);
|
||||
}
|
||||
write(">");
|
||||
}
|
||||
|
||||
|
@ -2611,12 +2627,6 @@ namespace ts {
|
|||
writer.decreaseIndent();
|
||||
}
|
||||
|
||||
function writeIfAny(nodes: NodeArray<Node>, text: string) {
|
||||
if (some(nodes)) {
|
||||
write(text);
|
||||
}
|
||||
}
|
||||
|
||||
function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) {
|
||||
return onEmitSourceMapOfToken
|
||||
? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
|
||||
|
@ -3176,7 +3186,7 @@ namespace ts {
|
|||
EnumMembers = CommaDelimited | Indented | MultiLine,
|
||||
CaseBlockClauses = Indented | MultiLine,
|
||||
NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces,
|
||||
JsxElementChildren = SingleLine | NoInterveningComments,
|
||||
JsxElementOrFragmentChildren = SingleLine | NoInterveningComments,
|
||||
JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty,
|
||||
HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
|
|
|
@ -2115,6 +2115,22 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
|
||||
const node = <JsxFragment>createSynthesizedNode(SyntaxKind.JsxFragment);
|
||||
node.openingFragment = openingFragment;
|
||||
node.children = createNodeArray(children);
|
||||
node.closingFragment = closingFragment;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
|
||||
return node.openingFragment !== openingFragment
|
||||
|| node.children !== children
|
||||
|| node.closingFragment !== closingFragment
|
||||
? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) {
|
||||
const node = <JsxAttribute>createSynthesizedNode(SyntaxKind.JsxAttribute);
|
||||
node.name = name;
|
||||
|
@ -2951,7 +2967,7 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) {
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) {
|
||||
// To ensure the emit resolver can properly resolve the namespace, we need to
|
||||
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
|
||||
// flag and setting a parent node.
|
||||
|
@ -2963,7 +2979,7 @@ namespace ts {
|
|||
return react;
|
||||
}
|
||||
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
if (isQualifiedName(jsxFactory)) {
|
||||
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
|
||||
const right = createIdentifier(idText(jsxFactory.right));
|
||||
|
@ -2975,7 +2991,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement): Expression {
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
return jsxFactoryEntity ?
|
||||
createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
|
||||
createPropertyAccess(
|
||||
|
@ -3016,6 +3032,37 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
|
||||
export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName, reactNamespace: string, children: Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
|
||||
const tagName = createPropertyAccess(
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"Fragment"
|
||||
);
|
||||
|
||||
const argumentsList = [<Expression>tagName];
|
||||
argumentsList.push(createNull());
|
||||
|
||||
if (children && children.length > 0) {
|
||||
if (children.length > 1) {
|
||||
for (const child of children) {
|
||||
child.startsOnNewLine = true;
|
||||
argumentsList.push(child);
|
||||
}
|
||||
}
|
||||
else {
|
||||
argumentsList.push(children[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsList
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
export function getHelperName(name: string) {
|
||||
|
|
|
@ -377,6 +377,10 @@ namespace ts {
|
|||
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
|
||||
visitNodes(cbNode, cbNodes, (<JsxElement>node).children) ||
|
||||
visitNode(cbNode, (<JsxElement>node).closingElement);
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitNode(cbNode, (<JsxFragment>node).openingFragment) ||
|
||||
visitNodes(cbNode, cbNodes, (<JsxFragment>node).children) ||
|
||||
visitNode(cbNode, (<JsxFragment>node).closingFragment);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
|
||||
|
@ -1423,6 +1427,11 @@ namespace ts {
|
|||
return tokenIsIdentifierOrKeyword(token());
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
|
||||
nextToken();
|
||||
return tokenIsIdentifierOrKeywordOrGreaterThan(token());
|
||||
}
|
||||
|
||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||
if (token() === SyntaxKind.ImplementsKeyword ||
|
||||
token() === SyntaxKind.ExtendsKeyword) {
|
||||
|
@ -3802,9 +3811,9 @@ namespace ts {
|
|||
node.operand = parseLeftHandSideExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeyword)) {
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
|
||||
// JSXElement is part of primaryExpression
|
||||
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
|
||||
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
|
||||
}
|
||||
|
||||
const expression = parseLeftHandSideExpressionOrHigher();
|
||||
|
@ -3959,14 +3968,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
|
||||
function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement {
|
||||
const opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
|
||||
let result: JsxElement | JsxSelfClosingElement;
|
||||
function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment {
|
||||
const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
|
||||
let result: JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
if (opening.kind === SyntaxKind.JsxOpeningElement) {
|
||||
const node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
|
||||
node.openingElement = opening;
|
||||
|
||||
node.children = parseJsxChildren(node.openingElement.tagName);
|
||||
node.children = parseJsxChildren(node.openingElement);
|
||||
node.closingElement = parseJsxClosingElement(inExpressionContext);
|
||||
|
||||
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
|
||||
|
@ -3975,6 +3984,14 @@ namespace ts {
|
|||
|
||||
result = finishNode(node);
|
||||
}
|
||||
else if (opening.kind === SyntaxKind.JsxOpeningFragment) {
|
||||
const node = <JsxFragment>createNode(SyntaxKind.JsxFragment, opening.pos);
|
||||
node.openingFragment = opening;
|
||||
node.children = parseJsxChildren(node.openingFragment);
|
||||
node.closingFragment = parseJsxClosingFragment(inExpressionContext);
|
||||
|
||||
result = finishNode(node);
|
||||
}
|
||||
else {
|
||||
Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement);
|
||||
// Nothing else to do for self-closing elements
|
||||
|
@ -3989,7 +4006,7 @@ namespace ts {
|
|||
// Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
|
||||
// of one sort or another.
|
||||
if (inExpressionContext && token() === SyntaxKind.LessThanToken) {
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true));
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true));
|
||||
if (invalidElement) {
|
||||
parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element);
|
||||
const badNode = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, result.pos);
|
||||
|
@ -4020,12 +4037,12 @@ namespace ts {
|
|||
case SyntaxKind.OpenBraceToken:
|
||||
return parseJsxExpression(/*inExpressionContext*/ false);
|
||||
case SyntaxKind.LessThanToken:
|
||||
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
|
||||
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
|
||||
}
|
||||
Debug.fail("Unknown JSX child kind " + token());
|
||||
}
|
||||
|
||||
function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray<JsxChild> {
|
||||
function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray<JsxChild> {
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
const saveParsingContext = parsingContext;
|
||||
|
@ -4040,7 +4057,13 @@ namespace ts {
|
|||
else if (token() === SyntaxKind.EndOfFileToken) {
|
||||
// If we hit EOF, issue the error at the tag that lacks the closing element
|
||||
// rather than at the end of the file (which is useless)
|
||||
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
|
||||
if (isJsxOpeningFragment(openingTag)) {
|
||||
parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
|
||||
}
|
||||
else {
|
||||
const openingTagName = openingTag.tagName;
|
||||
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (token() === SyntaxKind.ConflictMarkerTrivia) {
|
||||
|
@ -4063,11 +4086,17 @@ namespace ts {
|
|||
return finishNode(jsxAttributes);
|
||||
}
|
||||
|
||||
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
|
||||
function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment {
|
||||
const fullStart = scanner.getStartPos();
|
||||
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
|
||||
if (token() === SyntaxKind.GreaterThanToken) {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
const node: JsxOpeningFragment = <JsxOpeningFragment>createNode(SyntaxKind.JsxOpeningFragment, fullStart);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
const tagName = parseJsxElementName();
|
||||
const attributes = parseJsxAttributes();
|
||||
|
||||
|
@ -4179,6 +4208,23 @@ namespace ts {
|
|||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment {
|
||||
const node = <JsxClosingFragment>createNode(SyntaxKind.JsxClosingFragment);
|
||||
parseExpected(SyntaxKind.LessThanSlashToken);
|
||||
if (tokenIsIdentifierOrKeyword(token())) {
|
||||
const unexpectedTagName = parseJsxElementName();
|
||||
parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
|
||||
}
|
||||
if (inExpressionContext) {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
|
||||
scanJsxText();
|
||||
}
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTypeAssertion(): TypeAssertion {
|
||||
const node = <TypeAssertion>createNode(SyntaxKind.TypeAssertionExpression);
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
|
|
|
@ -11,6 +11,11 @@ namespace ts {
|
|||
return token >= SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean {
|
||||
return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token);
|
||||
}
|
||||
|
||||
export interface Scanner {
|
||||
getStartPos(): number;
|
||||
getToken(): SyntaxKind;
|
||||
|
|
|
@ -41,6 +41,9 @@ namespace ts {
|
|||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitJsxFragment(<JsxFragment>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxExpression:
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
|
||||
|
@ -63,6 +66,9 @@ namespace ts {
|
|||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ true);
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitJsxFragment(<JsxFragment>node, /*isChild*/ true);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
|
@ -77,6 +83,10 @@ namespace ts {
|
|||
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxFragment(node: JsxFragment, isChild: boolean) {
|
||||
return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
|
@ -126,6 +136,22 @@ namespace ts {
|
|||
return element;
|
||||
}
|
||||
|
||||
function visitJsxOpeningFragment(node: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const element = createExpressionForJsxFragment(
|
||||
context.getEmitResolver().getJsxFactoryEntity(),
|
||||
compilerOptions.reactNamespace,
|
||||
mapDefined(children, transformJsxChildToExpression),
|
||||
node,
|
||||
location
|
||||
);
|
||||
|
||||
if (isChild) {
|
||||
startOnNewLine(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
|
||||
return visitNode(node.expression, visitor, isExpression);
|
||||
}
|
||||
|
|
|
@ -328,6 +328,9 @@ namespace ts {
|
|||
JsxSelfClosingElement,
|
||||
JsxOpeningElement,
|
||||
JsxClosingElement,
|
||||
JsxFragment,
|
||||
JsxOpeningFragment,
|
||||
JsxClosingFragment,
|
||||
JsxAttribute,
|
||||
JsxAttributes,
|
||||
JsxSpreadAttribute,
|
||||
|
@ -1620,7 +1623,7 @@ namespace ts {
|
|||
closingElement: JsxClosingElement;
|
||||
}
|
||||
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair or the lone <Tag /> in a self-closing form
|
||||
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
|
||||
|
||||
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
|
||||
|
@ -1646,6 +1649,26 @@ namespace ts {
|
|||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
/// A JSX expression of the form <>...</>
|
||||
export interface JsxFragment extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxFragment;
|
||||
openingFragment: JsxOpeningFragment;
|
||||
children: NodeArray<JsxChild>;
|
||||
closingFragment: JsxClosingFragment;
|
||||
}
|
||||
|
||||
/// The opening element of a <>...</> JsxFragment
|
||||
export interface JsxOpeningFragment extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
|
||||
/// The closing element of a <>...</> JsxFragment
|
||||
export interface JsxClosingFragment extends Expression {
|
||||
kind: SyntaxKind.JsxClosingFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
|
||||
export interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxAttributes;
|
||||
|
@ -1679,7 +1702,7 @@ namespace ts {
|
|||
parent?: JsxElement;
|
||||
}
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
|
||||
export interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
|
|
|
@ -1262,6 +1262,7 @@ namespace ts {
|
|||
case SyntaxKind.OmittedExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.MetaProperty:
|
||||
|
@ -2170,6 +2171,7 @@ namespace ts {
|
|||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
|
@ -4794,6 +4796,18 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.JsxClosingElement;
|
||||
}
|
||||
|
||||
export function isJsxFragment(node: Node): node is JsxFragment {
|
||||
return node.kind === SyntaxKind.JsxFragment;
|
||||
}
|
||||
|
||||
export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment {
|
||||
return node.kind === SyntaxKind.JsxOpeningFragment;
|
||||
}
|
||||
|
||||
export function isJsxClosingFragment(node: Node): node is JsxClosingFragment {
|
||||
return node.kind === SyntaxKind.JsxClosingFragment;
|
||||
}
|
||||
|
||||
export function isJsxAttribute(node: Node): node is JsxAttribute {
|
||||
return node.kind === SyntaxKind.JsxAttribute;
|
||||
}
|
||||
|
@ -5319,6 +5333,7 @@ namespace ts {
|
|||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
|
@ -5640,7 +5655,8 @@ namespace ts {
|
|||
return kind === SyntaxKind.JsxElement
|
||||
|| kind === SyntaxKind.JsxExpression
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement
|
||||
|| kind === SyntaxKind.JsxText;
|
||||
|| kind === SyntaxKind.JsxText
|
||||
|| kind === SyntaxKind.JsxFragment;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
|
|
@ -819,6 +819,12 @@ namespace ts {
|
|||
return updateJsxClosingElement(<JsxClosingElement>node,
|
||||
visitNode((<JsxClosingElement>node).tagName, visitor, isJsxTagNameExpression));
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return updateJsxFragment(<JsxFragment>node,
|
||||
visitNode((<JsxFragment>node).openingFragment, visitor, isJsxOpeningFragment),
|
||||
nodesVisitor((<JsxFragment>node).children, visitor, isJsxChild),
|
||||
visitNode((<JsxFragment>node).closingFragment, visitor, isJsxClosingFragment));
|
||||
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return updateJsxAttribute(<JsxAttribute>node,
|
||||
visitNode((<JsxAttribute>node).name, visitor, isIdentifier),
|
||||
|
@ -1334,6 +1340,12 @@ namespace ts {
|
|||
result = reduceNode((<JsxElement>node).closingElement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
result = reduceNode((<JsxFragment>node).openingFragment, cbNode, result);
|
||||
result = reduceLeft((<JsxFragment>node).children, cbNode, result);
|
||||
result = reduceNode((<JsxFragment>node).closingFragment, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
|
||||
|
|
112
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
112
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
|
@ -313,46 +313,49 @@ declare namespace ts {
|
|||
JsxSelfClosingElement = 250,
|
||||
JsxOpeningElement = 251,
|
||||
JsxClosingElement = 252,
|
||||
JsxAttribute = 253,
|
||||
JsxAttributes = 254,
|
||||
JsxSpreadAttribute = 255,
|
||||
JsxExpression = 256,
|
||||
CaseClause = 257,
|
||||
DefaultClause = 258,
|
||||
HeritageClause = 259,
|
||||
CatchClause = 260,
|
||||
PropertyAssignment = 261,
|
||||
ShorthandPropertyAssignment = 262,
|
||||
SpreadAssignment = 263,
|
||||
EnumMember = 264,
|
||||
SourceFile = 265,
|
||||
Bundle = 266,
|
||||
JSDocTypeExpression = 267,
|
||||
JSDocAllType = 268,
|
||||
JSDocUnknownType = 269,
|
||||
JSDocNullableType = 270,
|
||||
JSDocNonNullableType = 271,
|
||||
JSDocOptionalType = 272,
|
||||
JSDocFunctionType = 273,
|
||||
JSDocVariadicType = 274,
|
||||
JSDocComment = 275,
|
||||
JSDocTypeLiteral = 276,
|
||||
JSDocTag = 277,
|
||||
JSDocAugmentsTag = 278,
|
||||
JSDocClassTag = 279,
|
||||
JSDocParameterTag = 280,
|
||||
JSDocReturnTag = 281,
|
||||
JSDocTypeTag = 282,
|
||||
JSDocTemplateTag = 283,
|
||||
JSDocTypedefTag = 284,
|
||||
JSDocPropertyTag = 285,
|
||||
SyntaxList = 286,
|
||||
NotEmittedStatement = 287,
|
||||
PartiallyEmittedExpression = 288,
|
||||
CommaListExpression = 289,
|
||||
MergeDeclarationMarker = 290,
|
||||
EndOfDeclarationMarker = 291,
|
||||
Count = 292,
|
||||
JsxFragment = 253,
|
||||
JsxOpeningFragment = 254,
|
||||
JsxClosingFragment = 255,
|
||||
JsxAttribute = 256,
|
||||
JsxAttributes = 257,
|
||||
JsxSpreadAttribute = 258,
|
||||
JsxExpression = 259,
|
||||
CaseClause = 260,
|
||||
DefaultClause = 261,
|
||||
HeritageClause = 262,
|
||||
CatchClause = 263,
|
||||
PropertyAssignment = 264,
|
||||
ShorthandPropertyAssignment = 265,
|
||||
SpreadAssignment = 266,
|
||||
EnumMember = 267,
|
||||
SourceFile = 268,
|
||||
Bundle = 269,
|
||||
JSDocTypeExpression = 270,
|
||||
JSDocAllType = 271,
|
||||
JSDocUnknownType = 272,
|
||||
JSDocNullableType = 273,
|
||||
JSDocNonNullableType = 274,
|
||||
JSDocOptionalType = 275,
|
||||
JSDocFunctionType = 276,
|
||||
JSDocVariadicType = 277,
|
||||
JSDocComment = 278,
|
||||
JSDocTypeLiteral = 279,
|
||||
JSDocTag = 280,
|
||||
JSDocAugmentsTag = 281,
|
||||
JSDocClassTag = 282,
|
||||
JSDocParameterTag = 283,
|
||||
JSDocReturnTag = 284,
|
||||
JSDocTypeTag = 285,
|
||||
JSDocTemplateTag = 286,
|
||||
JSDocTypedefTag = 287,
|
||||
JSDocPropertyTag = 288,
|
||||
SyntaxList = 289,
|
||||
NotEmittedStatement = 290,
|
||||
PartiallyEmittedExpression = 291,
|
||||
CommaListExpression = 292,
|
||||
MergeDeclarationMarker = 293,
|
||||
EndOfDeclarationMarker = 294,
|
||||
Count = 295,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
|
@ -378,10 +381,10 @@ declare namespace ts {
|
|||
FirstBinaryOperator = 27,
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 143,
|
||||
FirstJSDocNode = 267,
|
||||
LastJSDocNode = 285,
|
||||
FirstJSDocTagNode = 277,
|
||||
LastJSDocTagNode = 285,
|
||||
FirstJSDocNode = 270,
|
||||
LastJSDocNode = 288,
|
||||
FirstJSDocTagNode = 280,
|
||||
LastJSDocTagNode = 288,
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
|
@ -1061,6 +1064,20 @@ declare namespace ts {
|
|||
tagName: JsxTagNameExpression;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxFragment extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxFragment;
|
||||
openingFragment: JsxOpeningFragment;
|
||||
children: NodeArray<JsxChild>;
|
||||
closingFragment: JsxClosingFragment;
|
||||
}
|
||||
interface JsxOpeningFragment extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
interface JsxClosingFragment extends Expression {
|
||||
kind: SyntaxKind.JsxClosingFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxAttributes;
|
||||
|
@ -1088,7 +1105,7 @@ declare namespace ts {
|
|||
containsOnlyWhiteSpaces: boolean;
|
||||
parent?: JsxElement;
|
||||
}
|
||||
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
}
|
||||
|
@ -3002,6 +3019,9 @@ declare namespace ts {
|
|||
function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement;
|
||||
function isJsxOpeningElement(node: Node): node is JsxOpeningElement;
|
||||
function isJsxClosingElement(node: Node): node is JsxClosingElement;
|
||||
function isJsxFragment(node: Node): node is JsxFragment;
|
||||
function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment;
|
||||
function isJsxClosingFragment(node: Node): node is JsxClosingFragment;
|
||||
function isJsxAttribute(node: Node): node is JsxAttribute;
|
||||
function isJsxAttributes(node: Node): node is JsxAttributes;
|
||||
function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute;
|
||||
|
@ -3501,6 +3521,8 @@ declare namespace ts {
|
|||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, 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;
|
||||
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
|
||||
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
|
||||
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
|
||||
function createJsxAttributes(properties: ReadonlyArray<JsxAttributeLike>): JsxAttributes;
|
||||
|
|
112
tests/baselines/reference/api/typescript.d.ts
vendored
112
tests/baselines/reference/api/typescript.d.ts
vendored
|
@ -313,46 +313,49 @@ declare namespace ts {
|
|||
JsxSelfClosingElement = 250,
|
||||
JsxOpeningElement = 251,
|
||||
JsxClosingElement = 252,
|
||||
JsxAttribute = 253,
|
||||
JsxAttributes = 254,
|
||||
JsxSpreadAttribute = 255,
|
||||
JsxExpression = 256,
|
||||
CaseClause = 257,
|
||||
DefaultClause = 258,
|
||||
HeritageClause = 259,
|
||||
CatchClause = 260,
|
||||
PropertyAssignment = 261,
|
||||
ShorthandPropertyAssignment = 262,
|
||||
SpreadAssignment = 263,
|
||||
EnumMember = 264,
|
||||
SourceFile = 265,
|
||||
Bundle = 266,
|
||||
JSDocTypeExpression = 267,
|
||||
JSDocAllType = 268,
|
||||
JSDocUnknownType = 269,
|
||||
JSDocNullableType = 270,
|
||||
JSDocNonNullableType = 271,
|
||||
JSDocOptionalType = 272,
|
||||
JSDocFunctionType = 273,
|
||||
JSDocVariadicType = 274,
|
||||
JSDocComment = 275,
|
||||
JSDocTypeLiteral = 276,
|
||||
JSDocTag = 277,
|
||||
JSDocAugmentsTag = 278,
|
||||
JSDocClassTag = 279,
|
||||
JSDocParameterTag = 280,
|
||||
JSDocReturnTag = 281,
|
||||
JSDocTypeTag = 282,
|
||||
JSDocTemplateTag = 283,
|
||||
JSDocTypedefTag = 284,
|
||||
JSDocPropertyTag = 285,
|
||||
SyntaxList = 286,
|
||||
NotEmittedStatement = 287,
|
||||
PartiallyEmittedExpression = 288,
|
||||
CommaListExpression = 289,
|
||||
MergeDeclarationMarker = 290,
|
||||
EndOfDeclarationMarker = 291,
|
||||
Count = 292,
|
||||
JsxFragment = 253,
|
||||
JsxOpeningFragment = 254,
|
||||
JsxClosingFragment = 255,
|
||||
JsxAttribute = 256,
|
||||
JsxAttributes = 257,
|
||||
JsxSpreadAttribute = 258,
|
||||
JsxExpression = 259,
|
||||
CaseClause = 260,
|
||||
DefaultClause = 261,
|
||||
HeritageClause = 262,
|
||||
CatchClause = 263,
|
||||
PropertyAssignment = 264,
|
||||
ShorthandPropertyAssignment = 265,
|
||||
SpreadAssignment = 266,
|
||||
EnumMember = 267,
|
||||
SourceFile = 268,
|
||||
Bundle = 269,
|
||||
JSDocTypeExpression = 270,
|
||||
JSDocAllType = 271,
|
||||
JSDocUnknownType = 272,
|
||||
JSDocNullableType = 273,
|
||||
JSDocNonNullableType = 274,
|
||||
JSDocOptionalType = 275,
|
||||
JSDocFunctionType = 276,
|
||||
JSDocVariadicType = 277,
|
||||
JSDocComment = 278,
|
||||
JSDocTypeLiteral = 279,
|
||||
JSDocTag = 280,
|
||||
JSDocAugmentsTag = 281,
|
||||
JSDocClassTag = 282,
|
||||
JSDocParameterTag = 283,
|
||||
JSDocReturnTag = 284,
|
||||
JSDocTypeTag = 285,
|
||||
JSDocTemplateTag = 286,
|
||||
JSDocTypedefTag = 287,
|
||||
JSDocPropertyTag = 288,
|
||||
SyntaxList = 289,
|
||||
NotEmittedStatement = 290,
|
||||
PartiallyEmittedExpression = 291,
|
||||
CommaListExpression = 292,
|
||||
MergeDeclarationMarker = 293,
|
||||
EndOfDeclarationMarker = 294,
|
||||
Count = 295,
|
||||
FirstAssignment = 58,
|
||||
LastAssignment = 70,
|
||||
FirstCompoundAssignment = 59,
|
||||
|
@ -378,10 +381,10 @@ declare namespace ts {
|
|||
FirstBinaryOperator = 27,
|
||||
LastBinaryOperator = 70,
|
||||
FirstNode = 143,
|
||||
FirstJSDocNode = 267,
|
||||
LastJSDocNode = 285,
|
||||
FirstJSDocTagNode = 277,
|
||||
LastJSDocTagNode = 285,
|
||||
FirstJSDocNode = 270,
|
||||
LastJSDocNode = 288,
|
||||
FirstJSDocTagNode = 280,
|
||||
LastJSDocTagNode = 288,
|
||||
}
|
||||
enum NodeFlags {
|
||||
None = 0,
|
||||
|
@ -1061,6 +1064,20 @@ declare namespace ts {
|
|||
tagName: JsxTagNameExpression;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
interface JsxFragment extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxFragment;
|
||||
openingFragment: JsxOpeningFragment;
|
||||
children: NodeArray<JsxChild>;
|
||||
closingFragment: JsxClosingFragment;
|
||||
}
|
||||
interface JsxOpeningFragment extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
interface JsxClosingFragment extends Expression {
|
||||
kind: SyntaxKind.JsxClosingFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxAttributes;
|
||||
|
@ -1088,7 +1105,7 @@ declare namespace ts {
|
|||
containsOnlyWhiteSpaces: boolean;
|
||||
parent?: JsxElement;
|
||||
}
|
||||
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
}
|
||||
|
@ -3057,6 +3074,9 @@ declare namespace ts {
|
|||
function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement;
|
||||
function isJsxOpeningElement(node: Node): node is JsxOpeningElement;
|
||||
function isJsxClosingElement(node: Node): node is JsxClosingElement;
|
||||
function isJsxFragment(node: Node): node is JsxFragment;
|
||||
function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment;
|
||||
function isJsxClosingFragment(node: Node): node is JsxClosingFragment;
|
||||
function isJsxAttribute(node: Node): node is JsxAttribute;
|
||||
function isJsxAttributes(node: Node): node is JsxAttributes;
|
||||
function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute;
|
||||
|
@ -3448,6 +3468,8 @@ declare namespace ts {
|
|||
function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, 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;
|
||||
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
|
||||
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
|
||||
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
|
||||
function createJsxAttributes(properties: ReadonlyArray<JsxAttributeLike>): JsxAttributes;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
tests/cases/conformance/jsx/file.tsx(42,27): error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
|
||||
Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
|
||||
Types of property 'children' are incompatible.
|
||||
Type 'Element[]' is not assignable to type 'Element'.
|
||||
Property 'type' is missing in type 'Element[]'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string,
|
||||
children: JSX.Element | JSX.Element[];
|
||||
}
|
||||
|
||||
class Button extends React.Component<any, any> {
|
||||
render() {
|
||||
return (<div>My Button</div>)
|
||||
}
|
||||
}
|
||||
|
||||
function AnotherButton(p: any) {
|
||||
return <h1>Just Another Button</h1>;
|
||||
}
|
||||
|
||||
function Comp(p: Prop) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
|
||||
interface SingleChildProp {
|
||||
a: number,
|
||||
b: string,
|
||||
children: JSX.Element;
|
||||
}
|
||||
|
||||
function SingleChildComp(p: SingleChildProp) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
|
||||
// Error
|
||||
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & SingleChildProp'.
|
||||
!!! error TS2322: Type '{ a: 10; b: "hi"; children: Element[]; }' is not assignable to type 'SingleChildProp'.
|
||||
!!! error TS2322: Types of property 'children' are incompatible.
|
||||
!!! error TS2322: Type 'Element[]' is not assignable to type 'Element'.
|
||||
!!! error TS2322: Property 'type' is missing in type 'Element[]'.
|
85
tests/baselines/reference/checkJsxChildrenProperty14.js
Normal file
85
tests/baselines/reference/checkJsxChildrenProperty14.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
//// [file.tsx]
|
||||
import React = require('react');
|
||||
|
||||
interface Prop {
|
||||
a: number,
|
||||
b: string,
|
||||
children: JSX.Element | JSX.Element[];
|
||||
}
|
||||
|
||||
class Button extends React.Component<any, any> {
|
||||
render() {
|
||||
return (<div>My Button</div>)
|
||||
}
|
||||
}
|
||||
|
||||
function AnotherButton(p: any) {
|
||||
return <h1>Just Another Button</h1>;
|
||||
}
|
||||
|
||||
function Comp(p: Prop) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
|
||||
interface SingleChildProp {
|
||||
a: number,
|
||||
b: string,
|
||||
children: JSX.Element;
|
||||
}
|
||||
|
||||
function SingleChildComp(p: SingleChildProp) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
|
||||
// Error
|
||||
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
||||
|
||||
//// [file.jsx]
|
||||
"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 Button = /** @class */ (function (_super) {
|
||||
__extends(Button, _super);
|
||||
function Button() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Button.prototype.render = function () {
|
||||
return (<div>My Button</div>);
|
||||
};
|
||||
return Button;
|
||||
}(React.Component));
|
||||
function AnotherButton(p) {
|
||||
return <h1>Just Another Button</h1>;
|
||||
}
|
||||
function Comp(p) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
// OK
|
||||
var k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
var k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
var k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
function SingleChildComp(p) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
// OK
|
||||
var k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
// Error
|
||||
var k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
134
tests/baselines/reference/checkJsxChildrenProperty14.symbols
Normal file
134
tests/baselines/reference/checkJsxChildrenProperty14.symbols
Normal file
|
@ -0,0 +1,134 @@
|
|||
=== 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))
|
||||
|
||||
children: JSX.Element | JSX.Element[];
|
||||
>children : Symbol(Prop.children, Decl(file.tsx, 4, 14))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
|
||||
}
|
||||
|
||||
class Button extends React.Component<any, any> {
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>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))
|
||||
|
||||
render() {
|
||||
>render : Symbol(Button.render, Decl(file.tsx, 8, 48))
|
||||
|
||||
return (<div>My Button</div>)
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
}
|
||||
}
|
||||
|
||||
function AnotherButton(p: any) {
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>p : Symbol(p, Decl(file.tsx, 14, 23))
|
||||
|
||||
return <h1>Just Another Button</h1>;
|
||||
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47))
|
||||
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2410, 47))
|
||||
}
|
||||
|
||||
function Comp(p: Prop) {
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
>p : Symbol(p, Decl(file.tsx, 18, 14))
|
||||
>Prop : Symbol(Prop, Decl(file.tsx, 0, 32))
|
||||
|
||||
return <div>{p.b}</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
>p.b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
|
||||
>p : Symbol(p, Decl(file.tsx, 18, 14))
|
||||
>b : Symbol(Prop.b, Decl(file.tsx, 3, 14))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
}
|
||||
|
||||
// OK
|
||||
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
>k1 : Symbol(k1, Decl(file.tsx, 23, 3))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 23, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 23, 21))
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
|
||||
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
>k2 : Symbol(k2, Decl(file.tsx, 24, 3))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 24, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 24, 21))
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
|
||||
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
>k3 : Symbol(k3, Decl(file.tsx, 25, 3))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 25, 14))
|
||||
>b : Symbol(b, Decl(file.tsx, 25, 21))
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>Comp : Symbol(Comp, Decl(file.tsx, 16, 1))
|
||||
|
||||
interface SingleChildProp {
|
||||
>SingleChildProp : Symbol(SingleChildProp, Decl(file.tsx, 25, 69))
|
||||
|
||||
a: number,
|
||||
>a : Symbol(SingleChildProp.a, Decl(file.tsx, 27, 27))
|
||||
|
||||
b: string,
|
||||
>b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
|
||||
|
||||
children: JSX.Element;
|
||||
>children : Symbol(SingleChildProp.children, Decl(file.tsx, 29, 14))
|
||||
>JSX : Symbol(JSX, Decl(react.d.ts, 2353, 1))
|
||||
>Element : Symbol(JSX.Element, Decl(react.d.ts, 2356, 27))
|
||||
}
|
||||
|
||||
function SingleChildComp(p: SingleChildProp) {
|
||||
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
|
||||
>p : Symbol(p, Decl(file.tsx, 33, 25))
|
||||
>SingleChildProp : Symbol(SingleChildProp, Decl(file.tsx, 25, 69))
|
||||
|
||||
return <div>{p.b}</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
>p.b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
|
||||
>p : Symbol(p, Decl(file.tsx, 33, 25))
|
||||
>b : Symbol(SingleChildProp.b, Decl(file.tsx, 28, 14))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2400, 45))
|
||||
}
|
||||
|
||||
// OK
|
||||
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
>k4 : Symbol(k4, Decl(file.tsx, 38, 3))
|
||||
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 38, 25))
|
||||
>b : Symbol(b, Decl(file.tsx, 38, 32))
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
|
||||
|
||||
// Error
|
||||
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
||||
>k5 : Symbol(k5, Decl(file.tsx, 41, 3))
|
||||
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
|
||||
>a : Symbol(a, Decl(file.tsx, 41, 25))
|
||||
>b : Symbol(b, Decl(file.tsx, 41, 32))
|
||||
>Button : Symbol(Button, Decl(file.tsx, 6, 1))
|
||||
>AnotherButton : Symbol(AnotherButton, Decl(file.tsx, 12, 1))
|
||||
>SingleChildComp : Symbol(SingleChildComp, Decl(file.tsx, 31, 1))
|
||||
|
164
tests/baselines/reference/checkJsxChildrenProperty14.types
Normal file
164
tests/baselines/reference/checkJsxChildrenProperty14.types
Normal file
|
@ -0,0 +1,164 @@
|
|||
=== 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
|
||||
|
||||
children: JSX.Element | JSX.Element[];
|
||||
>children : JSX.Element | JSX.Element[]
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
}
|
||||
|
||||
class Button extends React.Component<any, any> {
|
||||
>Button : Button
|
||||
>React.Component : React.Component<any, any>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return (<div>My Button</div>)
|
||||
>(<div>My Button</div>) : JSX.Element
|
||||
><div>My Button</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
}
|
||||
}
|
||||
|
||||
function AnotherButton(p: any) {
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>p : any
|
||||
|
||||
return <h1>Just Another Button</h1>;
|
||||
><h1>Just Another Button</h1> : JSX.Element
|
||||
>h1 : any
|
||||
>h1 : any
|
||||
}
|
||||
|
||||
function Comp(p: Prop) {
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
>p : Prop
|
||||
>Prop : Prop
|
||||
|
||||
return <div>{p.b}</div>;
|
||||
><div>{p.b}</div> : JSX.Element
|
||||
>div : any
|
||||
>p.b : string
|
||||
>p : Prop
|
||||
>b : string
|
||||
>div : any
|
||||
}
|
||||
|
||||
// OK
|
||||
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
>k1 : JSX.Element
|
||||
><Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp> : JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
><></> : JSX.Element
|
||||
><Button /> : JSX.Element
|
||||
>Button : typeof Button
|
||||
><AnotherButton /> : JSX.Element
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
|
||||
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
>k2 : JSX.Element
|
||||
><Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp> : JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
><><Button /></> : JSX.Element
|
||||
><Button /> : JSX.Element
|
||||
>Button : typeof Button
|
||||
><AnotherButton /> : JSX.Element
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
|
||||
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
>k3 : JSX.Element
|
||||
><Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp> : JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
><><Button /><AnotherButton /></> : JSX.Element
|
||||
><Button /> : JSX.Element
|
||||
>Button : typeof Button
|
||||
><AnotherButton /> : JSX.Element
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>Comp : (p: Prop) => JSX.Element
|
||||
|
||||
interface SingleChildProp {
|
||||
>SingleChildProp : SingleChildProp
|
||||
|
||||
a: number,
|
||||
>a : number
|
||||
|
||||
b: string,
|
||||
>b : string
|
||||
|
||||
children: JSX.Element;
|
||||
>children : JSX.Element
|
||||
>JSX : any
|
||||
>Element : JSX.Element
|
||||
}
|
||||
|
||||
function SingleChildComp(p: SingleChildProp) {
|
||||
>SingleChildComp : (p: SingleChildProp) => JSX.Element
|
||||
>p : SingleChildProp
|
||||
>SingleChildProp : SingleChildProp
|
||||
|
||||
return <div>{p.b}</div>;
|
||||
><div>{p.b}</div> : JSX.Element
|
||||
>div : any
|
||||
>p.b : string
|
||||
>p : SingleChildProp
|
||||
>b : string
|
||||
>div : any
|
||||
}
|
||||
|
||||
// OK
|
||||
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
>k4 : JSX.Element
|
||||
><SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp> : JSX.Element
|
||||
>SingleChildComp : (p: SingleChildProp) => JSX.Element
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
><><Button /><AnotherButton /></> : JSX.Element
|
||||
><Button /> : JSX.Element
|
||||
>Button : typeof Button
|
||||
><AnotherButton /> : JSX.Element
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>SingleChildComp : (p: SingleChildProp) => JSX.Element
|
||||
|
||||
// Error
|
||||
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
||||
>k5 : JSX.Element
|
||||
><SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp> : JSX.Element
|
||||
>SingleChildComp : (p: SingleChildProp) => JSX.Element
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : string
|
||||
><></> : JSX.Element
|
||||
><Button /> : JSX.Element
|
||||
>Button : typeof Button
|
||||
><AnotherButton /> : JSX.Element
|
||||
>AnotherButton : (p: any) => JSX.Element
|
||||
>SingleChildComp : (p: SingleChildProp) => JSX.Element
|
||||
|
13
tests/baselines/reference/jsxFactoryAndFragment.errors.txt
Normal file
13
tests/baselines/reference/jsxFactoryAndFragment.errors.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
tests/cases/compiler/jsxFactoryAndFragment.tsx(3,1): error TS17016: JSX fragment is not supported when using --jsxFactory
|
||||
tests/cases/compiler/jsxFactoryAndFragment.tsx(4,1): error TS17016: JSX fragment is not supported when using --jsxFactory
|
||||
|
||||
|
||||
==== tests/cases/compiler/jsxFactoryAndFragment.tsx (2 errors) ====
|
||||
declare var h: any;
|
||||
|
||||
<></>;
|
||||
~~~~~
|
||||
!!! error TS17016: JSX fragment is not supported when using --jsxFactory
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS17016: JSX fragment is not supported when using --jsxFactory
|
13
tests/baselines/reference/jsxFactoryAndFragment.js
Normal file
13
tests/baselines/reference/jsxFactoryAndFragment.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
//// [jsxFactoryAndFragment.tsx]
|
||||
declare var h: any;
|
||||
|
||||
<></>;
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
|
||||
|
||||
//// [jsxFactoryAndFragment.js]
|
||||
h(React.Fragment, null);
|
||||
h(React.Fragment, null,
|
||||
h("span", null, "1"),
|
||||
h(React.Fragment, null,
|
||||
h("span", null, "2.1"),
|
||||
h("span", null, "2.2")));
|
13
tests/baselines/reference/jsxFactoryAndFragment.symbols
Normal file
13
tests/baselines/reference/jsxFactoryAndFragment.symbols
Normal file
|
@ -0,0 +1,13 @@
|
|||
=== tests/cases/compiler/jsxFactoryAndFragment.tsx ===
|
||||
declare var h: any;
|
||||
>h : Symbol(h, Decl(jsxFactoryAndFragment.tsx, 0, 11))
|
||||
|
||||
<></>;
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
|
||||
>span : Symbol(unknown)
|
||||
>span : Symbol(unknown)
|
||||
>span : Symbol(unknown)
|
||||
>span : Symbol(unknown)
|
||||
>span : Symbol(unknown)
|
||||
>span : Symbol(unknown)
|
||||
|
20
tests/baselines/reference/jsxFactoryAndFragment.types
Normal file
20
tests/baselines/reference/jsxFactoryAndFragment.types
Normal file
|
@ -0,0 +1,20 @@
|
|||
=== tests/cases/compiler/jsxFactoryAndFragment.tsx ===
|
||||
declare var h: any;
|
||||
>h : any
|
||||
|
||||
<></>;
|
||||
><></> : any
|
||||
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
|
||||
><><span>1</span><><span>2.1</span><span>2.2</span></></> : any
|
||||
><span>1</span> : any
|
||||
>span : any
|
||||
>span : any
|
||||
><><span>2.1</span><span>2.2</span></> : any
|
||||
><span>2.1</span> : any
|
||||
>span : any
|
||||
>span : any
|
||||
><span>2.2</span> : any
|
||||
>span : any
|
||||
>span : any
|
||||
|
25
tests/baselines/reference/tsxFragmentErrors.errors.txt
Normal file
25
tests/baselines/reference/tsxFragmentErrors.errors.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
tests/cases/conformance/jsx/file.tsx(9,7): error TS17015: Expected corresponding closing tag for JSX fragment.
|
||||
tests/cases/conformance/jsx/file.tsx(9,11): error TS17014: JSX fragment has no corresponding closing tag.
|
||||
tests/cases/conformance/jsx/file.tsx(11,17): error TS1005: '</' expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<>hi</div> // Error
|
||||
~~~
|
||||
!!! error TS17015: Expected corresponding closing tag for JSX fragment.
|
||||
~~~~~~~~~
|
||||
|
||||
|
||||
<>eof // Error
|
||||
~~
|
||||
!!! error TS17014: JSX fragment has no corresponding closing tag.
|
||||
|
||||
!!! error TS1005: '</' expected.
|
17
tests/baselines/reference/tsxFragmentErrors.js
Normal file
17
tests/baselines/reference/tsxFragmentErrors.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
//// [file.tsx]
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<>hi</div> // Error
|
||||
|
||||
<>eof // Error
|
||||
|
||||
//// [file.js]
|
||||
React.createElement(React.Fragment, null, "hi") // Error
|
||||
, // Error
|
||||
React.createElement(React.Fragment, null, "eof // Error");
|
20
tests/baselines/reference/tsxFragmentErrors.symbols
Normal file
20
tests/baselines/reference/tsxFragmentErrors.symbols
Normal file
|
@ -0,0 +1,20 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : Symbol(JSX, Decl(file.tsx, 0, 0))
|
||||
|
||||
interface Element { }
|
||||
>Element : Symbol(Element, Decl(file.tsx, 0, 20))
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
||||
[s: string]: any;
|
||||
>s : Symbol(s, Decl(file.tsx, 3, 3))
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : Symbol(React, Decl(file.tsx, 6, 11))
|
||||
|
||||
<>hi</div> // Error
|
||||
|
||||
<>eof // Error
|
24
tests/baselines/reference/tsxFragmentErrors.types
Normal file
24
tests/baselines/reference/tsxFragmentErrors.types
Normal file
|
@ -0,0 +1,24 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : any
|
||||
|
||||
interface Element { }
|
||||
>Element : Element
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : IntrinsicElements
|
||||
|
||||
[s: string]: any;
|
||||
>s : string
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : any
|
||||
|
||||
<>hi</div> // Error
|
||||
><>hi</div> // Error<>eof // Error : JSX.Element
|
||||
><>hi</div> : JSX.Element
|
||||
|
||||
<>eof // Error
|
||||
><>eof // Error : JSX.Element
|
||||
|
23
tests/baselines/reference/tsxFragmentPreserveEmit.js
Normal file
23
tests/baselines/reference/tsxFragmentPreserveEmit.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
//// [file.tsx]
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
|
||||
//// [file.jsx]
|
||||
<></>; // no whitespace
|
||||
<></>; // lots of whitespace
|
||||
<></>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
37
tests/baselines/reference/tsxFragmentPreserveEmit.symbols
Normal file
37
tests/baselines/reference/tsxFragmentPreserveEmit.symbols
Normal file
|
@ -0,0 +1,37 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : Symbol(JSX, Decl(file.tsx, 0, 0))
|
||||
|
||||
interface Element { }
|
||||
>Element : Symbol(Element, Decl(file.tsx, 0, 20))
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
||||
[s: string]: any;
|
||||
>s : Symbol(s, Decl(file.tsx, 3, 3))
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : Symbol(React, Decl(file.tsx, 6, 11))
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
54
tests/baselines/reference/tsxFragmentPreserveEmit.types
Normal file
54
tests/baselines/reference/tsxFragmentPreserveEmit.types
Normal file
|
@ -0,0 +1,54 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : any
|
||||
|
||||
interface Element { }
|
||||
>Element : Element
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : IntrinsicElements
|
||||
|
||||
[s: string]: any;
|
||||
>s : string
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : any
|
||||
|
||||
<></>; // no whitespace
|
||||
><></> : JSX.Element
|
||||
|
||||
< ></ >; // lots of whitespace
|
||||
>< ></ > : JSX.Element
|
||||
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
>< /*starting wrap*/ ></ /*ending wrap*/> : JSX.Element
|
||||
|
||||
<>hi</>; // text inside
|
||||
><>hi</> : JSX.Element
|
||||
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
><><span>hi</span><div>bye</div></> : JSX.Element
|
||||
><span>hi</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><div>bye</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
><><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></> : JSX.Element
|
||||
><span>1</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><><span>2.1</span><span>2.2</span></> : JSX.Element
|
||||
><span>2.1</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><span>2.2</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><span>3</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
|
30
tests/baselines/reference/tsxFragmentReactEmit.js
Normal file
30
tests/baselines/reference/tsxFragmentReactEmit.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
//// [file.tsx]
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
|
||||
//// [file.js]
|
||||
React.createElement(React.Fragment, null); // no whitespace
|
||||
React.createElement(React.Fragment, null); // lots of whitespace
|
||||
React.createElement(React.Fragment, null); // comments in the tags
|
||||
React.createElement(React.Fragment, null, "hi"); // text inside
|
||||
React.createElement(React.Fragment, null,
|
||||
React.createElement("span", null, "hi"),
|
||||
React.createElement("div", null, "bye")); // children
|
||||
React.createElement(React.Fragment, null,
|
||||
React.createElement("span", null, "1"),
|
||||
React.createElement(React.Fragment, null,
|
||||
React.createElement("span", null, "2.1"),
|
||||
React.createElement("span", null, "2.2")),
|
||||
React.createElement("span", null, "3")); // nested fragments
|
37
tests/baselines/reference/tsxFragmentReactEmit.symbols
Normal file
37
tests/baselines/reference/tsxFragmentReactEmit.symbols
Normal file
|
@ -0,0 +1,37 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : Symbol(JSX, Decl(file.tsx, 0, 0))
|
||||
|
||||
interface Element { }
|
||||
>Element : Symbol(Element, Decl(file.tsx, 0, 20))
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
||||
[s: string]: any;
|
||||
>s : Symbol(s, Decl(file.tsx, 3, 3))
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : Symbol(React, Decl(file.tsx, 6, 11))
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
>span : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
|
||||
|
54
tests/baselines/reference/tsxFragmentReactEmit.types
Normal file
54
tests/baselines/reference/tsxFragmentReactEmit.types
Normal file
|
@ -0,0 +1,54 @@
|
|||
=== tests/cases/conformance/jsx/file.tsx ===
|
||||
declare module JSX {
|
||||
>JSX : any
|
||||
|
||||
interface Element { }
|
||||
>Element : Element
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : IntrinsicElements
|
||||
|
||||
[s: string]: any;
|
||||
>s : string
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
>React : any
|
||||
|
||||
<></>; // no whitespace
|
||||
><></> : JSX.Element
|
||||
|
||||
< ></ >; // lots of whitespace
|
||||
>< ></ > : JSX.Element
|
||||
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
>< /*starting wrap*/ ></ /*ending wrap*/> : JSX.Element
|
||||
|
||||
<>hi</>; // text inside
|
||||
><>hi</> : JSX.Element
|
||||
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
><><span>hi</span><div>bye</div></> : JSX.Element
|
||||
><span>hi</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><div>bye</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
||||
><><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></> : JSX.Element
|
||||
><span>1</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><><span>2.1</span><span>2.2</span></> : JSX.Element
|
||||
><span>2.1</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><span>2.2</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
><span>3</span> : JSX.Element
|
||||
>span : any
|
||||
>span : any
|
||||
|
7
tests/cases/compiler/jsxFactoryAndFragment.tsx
Normal file
7
tests/cases/compiler/jsxFactoryAndFragment.tsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
//@jsx: react
|
||||
//@jsxfactory: h
|
||||
|
||||
declare var h: any;
|
||||
|
||||
<></>;
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></></>;
|
48
tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx
Normal file
48
tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
// @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,
|
||||
children: JSX.Element | JSX.Element[];
|
||||
}
|
||||
|
||||
class Button extends React.Component<any, any> {
|
||||
render() {
|
||||
return (<div>My Button</div>)
|
||||
}
|
||||
}
|
||||
|
||||
function AnotherButton(p: any) {
|
||||
return <h1>Just Another Button</h1>;
|
||||
}
|
||||
|
||||
function Comp(p: Prop) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k1 = <Comp a={10} b="hi"><></><Button /><AnotherButton /></Comp>;
|
||||
let k2 = <Comp a={10} b="hi"><><Button /></><AnotherButton /></Comp>;
|
||||
let k3 = <Comp a={10} b="hi"><><Button /><AnotherButton /></></Comp>;
|
||||
|
||||
interface SingleChildProp {
|
||||
a: number,
|
||||
b: string,
|
||||
children: JSX.Element;
|
||||
}
|
||||
|
||||
function SingleChildComp(p: SingleChildProp) {
|
||||
return <div>{p.b}</div>;
|
||||
}
|
||||
|
||||
// OK
|
||||
let k4 = <SingleChildComp a={10} b="hi"><><Button /><AnotherButton /></></SingleChildComp>;
|
||||
|
||||
// Error
|
||||
let k5 = <SingleChildComp a={10} b="hi"><></><Button /><AnotherButton /></SingleChildComp>;
|
14
tests/cases/conformance/jsx/tsxFragmentErrors.tsx
Normal file
14
tests/cases/conformance/jsx/tsxFragmentErrors.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
//@filename: file.tsx
|
||||
//@jsx: react
|
||||
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<>hi</div> // Error
|
||||
|
||||
<>eof // Error
|
17
tests/cases/conformance/jsx/tsxFragmentPreserveEmit.tsx
Normal file
17
tests/cases/conformance/jsx/tsxFragmentPreserveEmit.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
//@filename: file.tsx
|
||||
//@jsx: preserve
|
||||
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
17
tests/cases/conformance/jsx/tsxFragmentReactEmit.tsx
Normal file
17
tests/cases/conformance/jsx/tsxFragmentReactEmit.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
//@filename: file.tsx
|
||||
//@jsx: react
|
||||
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
[s: string]: any;
|
||||
}
|
||||
}
|
||||
declare var React: any;
|
||||
|
||||
<></>; // no whitespace
|
||||
< ></ >; // lots of whitespace
|
||||
< /*starting wrap*/ ></ /*ending wrap*/>; // comments in the tags
|
||||
<>hi</>; // text inside
|
||||
<><span>hi</span><div>bye</div></>; // children
|
||||
<><span>1</span><><span>2.1</span><span>2.2</span></><span>3</span></>; // nested fragments
|
Loading…
Reference in a new issue