From b3846bfe65ed6ee16fb9cd118c1630d0d701d907 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 7 Apr 2017 16:41:29 -0700 Subject: [PATCH 01/22] Wip - type checking JSX children --- src/compiler/checker.ts | 61 +++++++++++++++++----------- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/types.ts | 6 ++- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d7acedd663d94..ff10bea4f973a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1,4 +1,4 @@ -/// +/// /// /* @internal */ @@ -424,6 +424,8 @@ namespace ts { IntrinsicClassAttributes: "IntrinsicClassAttributes" }; + const jsxChildrenPropertyName = "children"; + const subtypeRelation = createMap(); const assignableRelation = createMap(); const comparableRelation = createMap(); @@ -8648,7 +8650,7 @@ namespace ts { // is considered known if the object type is empty and the check is for assignability, if the object type has // index signatures, or if the property is actually declared in the object type. In a union or intersection // type, a property is considered known if it is known in any constituent type. - function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean): boolean { + function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean, containsSynthesizedJsxChildren: boolean): boolean { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); if ((relation === assignableRelation || relation === comparableRelation) && @@ -8658,14 +8660,16 @@ namespace ts { else if (resolved.stringIndexInfo || (resolved.numberIndexInfo && isNumericLiteralName(name))) { return true; } - else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) { - // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. + else if (getPropertyOfType(type, name) || containsSynthesizedJsxChildren || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) { + // For JSXAttributes, consider that the attribute to be known if + // 1. the attribute has a hyphenated name + // 2. "children" attribute that is synthesized from children property of Jsx element return true; } } else if (type.flags & TypeFlags.UnionOrIntersection) { for (const t of (type).types) { - if (isKnownProperty(t, name, isComparingJsxAttributes)) { + if (isKnownProperty(t, name, isComparingJsxAttributes, containsSynthesizedJsxChildren)) { return true; } } @@ -8676,8 +8680,9 @@ namespace ts { function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes); + const containsSynthesizedJsxChildren = !!(source.flags & TypeFlags.ContainsSynthesizedJsxChildren); for (const prop of getPropertiesOfObjectType(source)) { - if (!isKnownProperty(target, prop.name, isComparingJsxAttributes)) { + if (!isKnownProperty(target, prop.name, isComparingJsxAttributes, containsSynthesizedJsxChildren)) { if (reportErrors) { // We know *exactly* where things went wrong when comparing the types. // Use this property as the error node as this will be more helpful in @@ -13173,21 +13178,6 @@ namespace ts { checkExpression(node.closingElement.tagName); } - // Check children - for (const child of node.children) { - switch (child.kind) { - case SyntaxKind.JsxExpression: - checkJsxExpression(child); - break; - case SyntaxKind.JsxElement: - checkJsxElement(child); - break; - case SyntaxKind.JsxSelfClosingElement: - checkJsxSelfClosingElement(child); - break; - } - } - return getJsxGlobalElementType() || anyType; } @@ -13280,6 +13270,30 @@ namespace ts { } }); } + + // Handle children attribute + const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? + openingLikeElement.parent as JsxElement : undefined; + let containsSynthesizedJsxChildren = false; + // Comment + if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) { + // Error if there is a attribute named "children" and children element. + // This is because children element will overwrite the value from attributes + if (attributesTable.has(jsxChildrenPropertyName)) { + error(attributes, Diagnostics.props_children_are_specified_twice_The_attribute_named_children_will_be_overwritten); + } + + // If there are children in the body of JSX element, create dummy attribute "children" with anyType so that it will pass the attribute checking process + const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName); + const childrenTypes: Type[] = []; + for (const child of (parent as JsxElement).children) { + childrenTypes.push(child.kind === SyntaxKind.JsxText ? stringType : checkExpression(child)); + } + childrenPropSymbol.type = getUnionType(childrenTypes, /*subtypeReduction*/ false); + attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol); + containsSynthesizedJsxChildren = true; + } + return createJsxAttributesType(attributes.symbol, attributesTable); /** @@ -13290,7 +13304,8 @@ namespace ts { function createJsxAttributesType(symbol: Symbol, attributesTable: Map) { const result = createAnonymousType(symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral; - result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag; + const containsSynthesizedJsxChildrenFlag = containsSynthesizedJsxChildren ? TypeFlags.ContainsSynthesizedJsxChildren : 0; + result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | containsSynthesizedJsxChildrenFlag; result.objectFlags |= ObjectFlags.ObjectLiteral; return result; } @@ -14533,7 +14548,7 @@ namespace ts { // We can figure that out by resolving attributes property and check number of properties in the resolved type // If the call has correct arity, we will then check if the argument type and parameter type is assignable - const callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incomplete + const callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incoplete if (callIsIncomplete) { return true; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 075d4247460e9..72554a9f0bacf 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2099,6 +2099,10 @@ "category": "Error", "code": 2707 }, + "props.children are specified twice. The attribute named 'children' will be overwritten.": { + "category": "Error", + "code": 2708 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 354ef9d8b1043..fd246fed82102 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1,4 +1,4 @@ -namespace ts { +namespace ts { /** * Type of objects whose values are all of the same type. * The `in` and `for-in` operators can *not* be safely used, @@ -10,7 +10,7 @@ namespace ts { /** ES6 Map interface. */ export interface Map { - get(key: string): T; + get(key: string): T | undefined; has(key: string): boolean; set(key: string, value: T): this; delete(key: string): boolean; @@ -2975,6 +2975,8 @@ namespace ts { NonPrimitive = 1 << 24, // intrinsic object type /* @internal */ JsxAttributes = 1 << 25, // Jsx attributes type + /* @internal */ + ContainsSynthesizedJsxChildren = 1 << 26, // Jsx attributes type contains synthesized children property from Jsx element's children /* @internal */ Nullable = Undefined | Null, From f86a730371c506d5ca9864b8d3a4b1835e1d4d47 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Apr 2017 10:52:18 -0700 Subject: [PATCH 02/22] Consider whitespace that won't be emitted to be different kind so that we won't include in typ-checking --- src/compiler/checker.ts | 15 ++++++--------- src/compiler/parser.ts | 8 ++++++-- src/compiler/scanner.ts | 21 ++++++++++++++++++++- src/compiler/types.ts | 1 + 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff10bea4f973a..2c9d4f95d5f88 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13275,7 +13275,7 @@ namespace ts { const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : undefined; let containsSynthesizedJsxChildren = false; - // Comment + // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) { // Error if there is a attribute named "children" and children element. // This is because children element will overwrite the value from attributes @@ -13287,7 +13287,11 @@ namespace ts { const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName); const childrenTypes: Type[] = []; for (const child of (parent as JsxElement).children) { - childrenTypes.push(child.kind === SyntaxKind.JsxText ? stringType : checkExpression(child)); + // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that + // because then type of children property will have constituent of string type. + if (child.kind !== SyntaxKind.JsxTextAllWhiteSpaces) { + childrenTypes.push(child.kind === SyntaxKind.JsxText ? stringType : checkExpression(child as Expression, checkMode)); + } } childrenPropSymbol.type = getUnionType(childrenTypes, /*subtypeReduction*/ false); attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol); @@ -17099,13 +17103,6 @@ namespace ts { return cache ? checkExpressionCached(node) : checkExpression(node); } - // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When - // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the - // expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in - // conjunction with the generic contextual type. When contextualMapper is equal to the identityMapper function - // object, it serves as an indicator that all contained function and arrow expressions should be considered to - // have the wildcard function type; this form of type check is used during overload resolution to exclude - // contextually typed function and arrow expressions in the initial phase. function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode): Type { let type: Type; if (node.kind === SyntaxKind.QualifiedName) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a82d5b02b4402..770601bd56cd8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3825,7 +3825,7 @@ namespace ts { } function parseJsxText(): JsxText { - const node = createNode(SyntaxKind.JsxText, scanner.getStartPos()); + const node = createNode(currentToken, scanner.getStartPos()); currentToken = scanner.scanJsxToken(); return finishNode(node); } @@ -3833,6 +3833,7 @@ namespace ts { function parseJsxChild(): JsxChild { switch (token()) { case SyntaxKind.JsxText: + case SyntaxKind.JsxTextAllWhiteSpaces: return parseJsxText(); case SyntaxKind.OpenBraceToken: return parseJsxExpression(/*inExpressionContext*/ false); @@ -3862,7 +3863,10 @@ namespace ts { else if (token() === SyntaxKind.ConflictMarkerTrivia) { break; } - result.push(parseJsxChild()); + const child = parseJsxChild(); + if (child) { + result.push(child); + } } result.end = scanner.getTokenPos(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 7b6e0c09db48b..59453f4fa4b28 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1723,6 +1723,11 @@ namespace ts { return token = SyntaxKind.OpenBraceToken; } + // First non-whitespace character on this line. + let firstNonWhitespace = 0; + // These initial values are special because the first line is: + // firstNonWhitespace = 0 to indicate that we want leading whitspace, + while (pos < end) { pos++; char = text.charCodeAt(pos); @@ -1736,8 +1741,22 @@ namespace ts { } break; } + + // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. + // i.e (- : whitespace) + //
---- + //
becomes
+ // + //
----
becomes
----
+ if (isLineBreak(char) && firstNonWhitespace === 0) { + firstNonWhitespace = -1; + } + else if (!isWhiteSpaceSingleLine(char)) { + firstNonWhitespace = pos; + } } - return token = SyntaxKind.JsxText; + + return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText; } // Scans a JSX identifier; these differ from normal identifiers in that diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fd246fed82102..0e0deeedfaa3b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -65,6 +65,7 @@ NumericLiteral, StringLiteral, JsxText, + JsxTextAllWhiteSpaces, RegularExpressionLiteral, NoSubstitutionTemplateLiteral, // Pseudo-literals From 8e2dd382679be99b680b14df9c34334675844d83 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Apr 2017 10:52:50 -0700 Subject: [PATCH 03/22] Use JSX Attributes to contextually type children property --- src/compiler/checker.ts | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2c9d4f95d5f88..62fabf8b85a75 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12635,6 +12635,35 @@ namespace ts { return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } + function getContextualTypeForJsxExpression(node: JsxExpression): Type { + // 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 + + // 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. + // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName + const attributesType = getContextualType(jsxAttributes); + + if (!attributesType || isTypeAny(attributesType)) { + return undefined; + } + + if (isJsxAttribute(node.parent)) { + // JSX expression is in JSX attribute + return getTypeOfPropertyOfType(attributesType, (node.parent as JsxAttribute).name.text); + } + else if (node.parent.kind === SyntaxKind.JsxElement) { + // JSX expression is in children of JSX Element, we will look for an atttribute named "chidlren" + return getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName); + } + else { + // JSX expression is in JSX spread attribute + return attributesType; + } + } + function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { // 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. @@ -12718,7 +12747,7 @@ namespace ts { case SyntaxKind.ParenthesizedExpression: return getContextualType(parent); case SyntaxKind.JsxExpression: - return getContextualType(parent); + return getContextualTypeForJsxExpression(parent); case SyntaxKind.JsxAttribute: case SyntaxKind.JsxSpreadAttribute: return getContextualTypeForJsxAttribute(parent); From 17417e9a88f2fdb738d7a72f8a012ca43657d03c Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Apr 2017 10:53:14 -0700 Subject: [PATCH 04/22] Format checker --- src/compiler/checker.ts | 68 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62fabf8b85a75..7bbab7005fd13 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -349,7 +349,7 @@ namespace ts { // The presence of a particular fact means that the given test is true for some (and possibly all) values // of that kind of type. BaseStringStrictFacts = TypeofEQString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | NEUndefined | NENull | NEUndefinedOrNull, - BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, + BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy, StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy, StringFacts = BaseStringFacts | Truthy, EmptyStringStrictFacts = BaseStringStrictFacts | Falsy, @@ -1618,7 +1618,7 @@ namespace ts { } } - // May be an untyped module. If so, ignore resolutionDiagnostic. + // May be an untyped module. If so, ignore resolutionDiagnostic. if (!isRelative && resolvedModule && !extensionIsTypeScript(resolvedModule.extension)) { if (isForAugmentation) { const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; @@ -3973,7 +3973,7 @@ namespace ts { type; } - function getTypeForDeclarationFromJSDocComment(declaration: Node ) { + function getTypeForDeclarationFromJSDocComment(declaration: Node) { const jsdocType = getJSDocType(declaration); if (jsdocType) { return getTypeFromTypeNode(jsdocType); @@ -5640,7 +5640,7 @@ namespace ts { function getConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type { return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type) : type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type) : - getBaseConstraintOfType(type); + getBaseConstraintOfType(type); } function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type { @@ -5713,7 +5713,7 @@ namespace ts { } return t.flags & TypeFlags.Union && baseTypes.length === types.length ? getUnionType(baseTypes) : t.flags & TypeFlags.Intersection && baseTypes.length ? getIntersectionType(baseTypes) : - undefined; + undefined; } if (t.flags & TypeFlags.Index) { return stringType; @@ -5764,11 +5764,11 @@ namespace ts { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : t.flags & TypeFlags.StringLike ? globalStringType : - t.flags & TypeFlags.NumberLike ? globalNumberType : - t.flags & TypeFlags.BooleanLike ? globalBooleanType : - t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? emptyObjectType : - t; + t.flags & TypeFlags.NumberLike ? globalNumberType : + t.flags & TypeFlags.BooleanLike ? globalBooleanType : + t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : + t; } function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { @@ -7212,8 +7212,8 @@ namespace ts { function getIndexType(type: Type): Type { return maybeTypeOfKind(type, TypeFlags.TypeVariable) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : - getLiteralTypeFromPropertyNames(type); + type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : + getLiteralTypeFromPropertyNames(type); } function getIndexTypeOrString(type: Type): Type { @@ -7409,7 +7409,7 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type): Type { + function getSpreadType(left: Type, right: Type): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } @@ -7698,7 +7698,7 @@ namespace ts { function createTypeMapper(sources: Type[], targets: Type[]): TypeMapper { const mapper: TypeMapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : - makeArrayTypeMapper(sources, targets); + makeArrayTypeMapper(sources, targets); mapper.mappedTypes = sources; return mapper; } @@ -8502,7 +8502,7 @@ namespace ts { (globalNumberType === source && numberType === target) || (globalBooleanType === source && booleanType === target) || (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) { - reportError(Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType); + reportError(Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType); } } @@ -9631,25 +9631,25 @@ namespace ts { function isLiteralType(type: Type): boolean { return type.flags & TypeFlags.Boolean ? true : type.flags & TypeFlags.Union ? type.flags & TypeFlags.Enum ? true : !forEach((type).types, t => !isUnitType(t)) : - isUnitType(type); + isUnitType(type); } function getBaseTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.StringLiteral ? stringType : type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.EnumLiteral ? (type).baseType : - type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : - type; + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.EnumLiteral ? (type).baseType : + type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : + type; } function getWidenedLiteralType(type: Type): Type { return type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType : type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.EnumLiteral ? (type).baseType : - type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : - type; + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.EnumLiteral ? (type).baseType : + type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum) ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : + type; } /** @@ -9674,9 +9674,9 @@ namespace ts { function getFalsyFlags(type: Type): TypeFlags { return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type).types) : type.flags & TypeFlags.StringLiteral ? (type).text === "" ? TypeFlags.StringLiteral : 0 : - type.flags & TypeFlags.NumberLiteral ? (type).text === "0" ? TypeFlags.NumberLiteral : 0 : - type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : - type.flags & TypeFlags.PossiblyFalsy; + type.flags & TypeFlags.NumberLiteral ? (type).text === "0" ? TypeFlags.NumberLiteral : 0 : + type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : + type.flags & TypeFlags.PossiblyFalsy; } function includeFalsyTypes(type: Type, flags: TypeFlags) { @@ -10862,8 +10862,8 @@ namespace ts { isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.NumberLiteral)) { return mapType(typeWithPrimitives, t => t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral) : - t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) : - t); + t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) : + t); } return typeWithPrimitives; } @@ -11439,7 +11439,7 @@ namespace ts { const discriminantType = getUnionType(clauseTypes); const caseType = discriminantType.flags & TypeFlags.Never ? neverType : - replacePrimitivesWithLiterals(filterType(type, t => isTypeComparableTo(discriminantType, t)), discriminantType); + replacePrimitivesWithLiterals(filterType(type, t => isTypeComparableTo(discriminantType, t)), discriminantType); if (!hasDefaultClause) { return caseType; } @@ -11519,8 +11519,8 @@ namespace ts { // two types. return isTypeSubtypeOf(candidate, type) ? candidate : isTypeAssignableTo(type, candidate) ? type : - isTypeAssignableTo(candidate, type) ? candidate : - getIntersectionType([type, candidate]); + isTypeAssignableTo(candidate, type) ? candidate : + getIntersectionType([type, candidate]); } function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { @@ -11797,7 +11797,7 @@ namespace ts { isInAmbientContext(declaration); const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) : type === autoType || type === autoArrayType ? undefinedType : - includeFalsyTypes(type, TypeFlags.Undefined); + includeFalsyTypes(type, TypeFlags.Undefined); const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized); // A variable is considered uninitialized when it is possible to analyze the entire control flow graph // from declaration to use, and when the variable's declared type doesn't include undefined but the @@ -12304,7 +12304,7 @@ namespace ts { func.kind === SyntaxKind.GetAccessor || func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? func.parent.parent : - undefined; + undefined; } function getThisTypeArgument(type: Type): Type { From 4562fd089cd19f0f49fe57be9a8a6af800983f98 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Apr 2017 14:55:26 -0700 Subject: [PATCH 05/22] Store scanning information whether JSXText is just an all whitespaces --- src/compiler/checker.ts | 9 +++++++-- src/compiler/parser.ts | 3 ++- src/compiler/scanner.ts | 2 +- src/compiler/types.ts | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bbab7005fd13..18ad0c0437c2f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13318,8 +13318,13 @@ namespace ts { for (const child of (parent as JsxElement).children) { // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that // because then type of children property will have constituent of string type. - if (child.kind !== SyntaxKind.JsxTextAllWhiteSpaces) { - childrenTypes.push(child.kind === SyntaxKind.JsxText ? stringType : checkExpression(child as Expression, checkMode)); + if (child.kind === SyntaxKind.JsxText) { + if (!child.containsOnlyWhiteSpaces) { + childrenTypes.push(stringType); + } + } + else { + childrenTypes.push(checkExpression(child, checkMode)); } } childrenPropSymbol.type = getUnionType(childrenTypes, /*subtypeReduction*/ false); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 770601bd56cd8..cc18fb3260c99 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3825,7 +3825,8 @@ namespace ts { } function parseJsxText(): JsxText { - const node = createNode(currentToken, scanner.getStartPos()); + const node = createNode(SyntaxKind.JsxText, scanner.getStartPos()); + node.containsOnlyWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces; currentToken = scanner.scanJsxToken(); return finishNode(node); } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 59453f4fa4b28..2d7ca500893db 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1729,7 +1729,6 @@ namespace ts { // firstNonWhitespace = 0 to indicate that we want leading whitspace, while (pos < end) { - pos++; char = text.charCodeAt(pos); if (char === CharacterCodes.openBrace) { break; @@ -1754,6 +1753,7 @@ namespace ts { else if (!isWhiteSpaceSingleLine(char)) { firstNonWhitespace = pos; } + pos++; } return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0e0deeedfaa3b..d52f277c9ef2d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1572,7 +1572,8 @@ } export interface JsxText extends Node { - kind: SyntaxKind.JsxText; + kind: SyntaxKind.JsxText, + containsOnlyWhiteSpaces: boolean, parent?: JsxElement; } From c1ea3034d5d02b22ef192939704cc77b97657ce0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 11 Apr 2017 15:35:06 -0700 Subject: [PATCH 06/22] wip-fixing consuming whitespace in children --- src/compiler/emitter.ts | 2 +- src/compiler/scanner.ts | 8 ++++---- src/services/formatting/smartIndenter.ts | 2 +- src/services/textChanges.ts | 2 +- src/services/utilities.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 69b5188878f86..669c9f5dd36ee 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2457,7 +2457,7 @@ namespace ts { let indentation: number; for (const line of lines) { for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) { - if (!isWhiteSpace(line.charCodeAt(i))) { + if (!isWhiteSpaceLike(line.charCodeAt(i))) { if (indentation === undefined || i < indentation) { indentation = i; break; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 2d7ca500893db..86699702c3b36 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -366,7 +366,7 @@ namespace ts { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } - export function isWhiteSpace(ch: number): boolean { + export function isWhiteSpaceLike(ch: number): boolean { return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); } @@ -510,7 +510,7 @@ namespace ts { break; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) { + if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { pos++; continue; } @@ -691,7 +691,7 @@ namespace ts { } break scan; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) { + if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { if (hasPendingCommentRange && isLineBreak(ch)) { pendingHasTrailingNewLine = true; } @@ -1750,7 +1750,7 @@ namespace ts { if (isLineBreak(char) && firstNonWhitespace === 0) { firstNonWhitespace = -1; } - else if (!isWhiteSpaceSingleLine(char)) { + else if (!isWhiteSpaceLike(char) && (char !== CharacterCodes.openBrace || char !== CharacterCodes.lessThan)) { firstNonWhitespace = pos; } pos++; diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b5c901482a7bc..01feaf390818e 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -54,7 +54,7 @@ namespace ts.formatting { let current = position; while (current > 0) { const char = sourceFile.text.charCodeAt(current); - if (!isWhiteSpace(char)) { + if (!isWhiteSpaceLike(char)) { break; } current--; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index d7056cfdca241..e63c46ea8cedd 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -608,7 +608,7 @@ namespace ts.textChanges { if (force || !isTrivia(s)) { this.lastNonTriviaPosition = this.writer.getTextPos(); let i = 0; - while (isWhiteSpace(s.charCodeAt(s.length - i - 1))) { + while (isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { i++; } // trim trailing whitespaces diff --git a/src/services/utilities.ts b/src/services/utilities.ts index fe9a310ad4bf7..5a1acdf1cec09 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1381,7 +1381,7 @@ namespace ts { } export function getFirstNonSpaceCharacterPosition(text: string, position: number) { - while (isWhiteSpace(text.charCodeAt(position))) { + while (isWhiteSpaceLike(text.charCodeAt(position))) { position += 1; } return position; From 4fa23127fcd9281c39e87120d5f690ec293a7fd8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 12 Apr 2017 12:08:12 -0700 Subject: [PATCH 07/22] Fixing consuming whitespace in children --- src/compiler/checker.ts | 4 +++- src/compiler/emitter.ts | 2 +- src/compiler/scanner.ts | 8 ++++---- src/compiler/types.ts | 4 ++-- src/services/formatting/smartIndenter.ts | 2 +- src/services/textChanges.ts | 2 +- src/services/utilities.ts | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 18ad0c0437c2f..745d38bd04341 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13327,7 +13327,9 @@ namespace ts { childrenTypes.push(checkExpression(child, checkMode)); } } - childrenPropSymbol.type = getUnionType(childrenTypes, /*subtypeReduction*/ false); + childrenPropSymbol.type = childrenTypes.length === 1 ? + childrenTypes[0] : + createArrayType(getUnionType(childrenTypes, /*subtypeReduction*/ false)); attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol); containsSynthesizedJsxChildren = true; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 69b5188878f86..669c9f5dd36ee 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2457,7 +2457,7 @@ namespace ts { let indentation: number; for (const line of lines) { for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) { - if (!isWhiteSpace(line.charCodeAt(i))) { + if (!isWhiteSpaceLike(line.charCodeAt(i))) { if (indentation === undefined || i < indentation) { indentation = i; break; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 2d7ca500893db..8f2cacd3e385a 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -366,7 +366,7 @@ namespace ts { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } - export function isWhiteSpace(ch: number): boolean { + export function isWhiteSpaceLike(ch: number): boolean { return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); } @@ -510,7 +510,7 @@ namespace ts { break; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) { + if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { pos++; continue; } @@ -691,7 +691,7 @@ namespace ts { } break scan; default: - if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch))) { + if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { if (hasPendingCommentRange && isLineBreak(ch)) { pendingHasTrailingNewLine = true; } @@ -1750,7 +1750,7 @@ namespace ts { if (isLineBreak(char) && firstNonWhitespace === 0) { firstNonWhitespace = -1; } - else if (!isWhiteSpaceSingleLine(char)) { + else if (!isWhiteSpaceLike(char)) { firstNonWhitespace = pos; } pos++; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d52f277c9ef2d..fe415431c77eb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1572,8 +1572,8 @@ } export interface JsxText extends Node { - kind: SyntaxKind.JsxText, - containsOnlyWhiteSpaces: boolean, + kind: SyntaxKind.JsxText; + containsOnlyWhiteSpaces: boolean; parent?: JsxElement; } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b5c901482a7bc..01feaf390818e 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -54,7 +54,7 @@ namespace ts.formatting { let current = position; while (current > 0) { const char = sourceFile.text.charCodeAt(current); - if (!isWhiteSpace(char)) { + if (!isWhiteSpaceLike(char)) { break; } current--; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index d7056cfdca241..e63c46ea8cedd 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -608,7 +608,7 @@ namespace ts.textChanges { if (force || !isTrivia(s)) { this.lastNonTriviaPosition = this.writer.getTextPos(); let i = 0; - while (isWhiteSpace(s.charCodeAt(s.length - i - 1))) { + while (isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { i++; } // trim trailing whitespaces diff --git a/src/services/utilities.ts b/src/services/utilities.ts index fe9a310ad4bf7..5a1acdf1cec09 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1381,7 +1381,7 @@ namespace ts { } export function getFirstNonSpaceCharacterPosition(text: string, position: number) { - while (isWhiteSpace(text.charCodeAt(position))) { + while (isWhiteSpaceLike(text.charCodeAt(position))) { position += 1; } return position; From f0990460a62bda901a0548f3d7e6a579cd06ccce Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 12 Apr 2017 12:17:27 -0700 Subject: [PATCH 08/22] Add tests --- .../jsx/checkJsxChildrenProperty1.tsx | 27 ++++++++++ .../jsx/checkJsxChildrenProperty2.tsx | 49 +++++++++++++++++++ .../jsx/checkJsxChildrenProperty3.tsx | 44 +++++++++++++++++ .../jsx/checkJsxChildrenProperty4.tsx | 49 +++++++++++++++++++ .../jsx/checkJsxChildrenProperty5.tsx | 35 +++++++++++++ .../jsx/checkJsxChildrenProperty6.tsx | 48 ++++++++++++++++++ .../jsx/checkJsxChildrenProperty7.tsx | 33 +++++++++++++ .../jsx/checkJsxChildrenProperty8.tsx | 34 +++++++++++++ ...tsxStatelessFunctionComponentOverload6.tsx | 2 +- ...nInFunctionExpressionOfChildrenCallback.ts | 31 ++++++++++++ 10 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty1.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty2.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty3.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty4.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty5.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty6.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty7.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty8.tsx create mode 100644 tests/cases/fourslash/tscCompletionInFunctionExpressionOfChildrenCallback.ts diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty1.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty1.tsx new file mode 100644 index 0000000000000..70b58c03f6ac1 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty1.tsx @@ -0,0 +1,27 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + a: number, + b: string, + children: string | JSX.Element +} + +function Comp(p: Prop) { + return
{p.b}
; +} + +// OK +let k = ; +let k1 = + + hi hi hi! + ; +let k2 = + +
hi hi hi!
+
; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty2.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty2.tsx new file mode 100644 index 0000000000000..0c78f8f41255b --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty2.tsx @@ -0,0 +1,49 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + a: number, + b: string, + children: string | JSX.Element +} + +function Comp(p: Prop) { + return
{p.b}
; +} + +// Error: missing children +let k = ; + +let k1 = + + hi hi hi! + ; + +// Error: incorrect type +let k2 = + +
My Div
+ {(name: string) =>
My name {name}
} +
; + +let k3 = + +
My Div
+ {1000000} +
; + +let k4 = + +
My Div
+ hi hi hi! +
; + +let k5 = + +
My Div
+
My Div
+
; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty3.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty3.tsx new file mode 100644 index 0000000000000..c67c6d5440dce --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty3.tsx @@ -0,0 +1,44 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface IUser { + Name: string; +} + +interface IFetchUserProps { + children: (user: IUser) => JSX.Element; +} + +class FetchUser extends React.Component { + render() { + return this.state + ? this.props.children(this.state.result) + : null; + } +} + +// Ok +function UserName0() { + return ( + + { user => ( +

{ user.Name }

+ ) } +
+ ); +} + +function UserName1() { + return ( + + + { user => ( +

{ user.Name }

+ ) } +
+ ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty4.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty4.tsx new file mode 100644 index 0000000000000..34877f2000cd3 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty4.tsx @@ -0,0 +1,49 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface IUser { + Name: string; +} + +interface IFetchUserProps { + children: (user: IUser) => JSX.Element; +} + +class FetchUser extends React.Component { + render() { + return this.state + ? this.props.children(this.state.result) + : null; + } +} + +// Error +function UserName() { + return ( + + { user => ( +

{ user.NAme }

+ ) } +
+ ); +} + +function UserName1() { + return ( + + + + + { user => ( +

{ user.Name }

+ ) } + { user => ( +

{ user.Name }

+ ) } +
+ ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty5.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty5.tsx new file mode 100644 index 0000000000000..6143e4b0fafa9 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty5.tsx @@ -0,0 +1,35 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + a: number, + b: string, + children: Button; +} + +class Button extends React.Component { + render() { + return (
My Button
) + } +} + +function Comp(p: Prop) { + return
{p.b}
; +} + +// Error: no children specified +let k = ; + +// Error: JSX.element is not the same as JSX.ElementClass +let k1 = + + ; + +//// [file.jsx] +var Button = (function () { + function Button() { + } + Button.prototype.render = function () { + return (
My Button
); + }; + return Button; +}()); +// OK +var k1 =

Hello

world

; +var k2 =

Hello

{function (user) { return

{user.name}

; }}
; +var k3 =
{1} {"That is a number"}
; +var k4 = ; diff --git a/tests/baselines/reference/checkJsxChildrenProperty10.symbols b/tests/baselines/reference/checkJsxChildrenProperty10.symbols new file mode 100644 index 0000000000000..bf054377fb16a --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty10.symbols @@ -0,0 +1,73 @@ +=== 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 ElementAttributesProperty { props: {} } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(file.tsx, 1, 22)) +>props : Symbol(ElementAttributesProperty.props, Decl(file.tsx, 2, 38)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 50)) + + div: any; +>div : Symbol(IntrinsicElements.div, Decl(file.tsx, 3, 30)) + + h2: any; +>h2 : Symbol(IntrinsicElements.h2, Decl(file.tsx, 4, 11)) + + h1: any; +>h1 : Symbol(IntrinsicElements.h1, Decl(file.tsx, 5, 10)) + } +} + +class Button { +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) + + props: {} +>props : Symbol(Button.props, Decl(file.tsx, 10, 14)) + + render() { +>render : Symbol(Button.render, Decl(file.tsx, 11, 10)) + + return (
My Button
) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + } +} + +// OK +let k1 =

Hello

world

; +>k1 : Symbol(k1, Decl(file.tsx, 18, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(file.tsx, 5, 10)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(file.tsx, 5, 10)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +>k2 : Symbol(k2, Decl(file.tsx, 19, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>user : Symbol(user, Decl(file.tsx, 19, 34)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>user : Symbol(user, Decl(file.tsx, 19, 34)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k3 =
{1} {"That is a number"}
; +>k3 : Symbol(k3, Decl(file.tsx, 20, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k4 = ; +>k4 : Symbol(k4, Decl(file.tsx, 21, 3)) +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) + diff --git a/tests/baselines/reference/checkJsxChildrenProperty10.types b/tests/baselines/reference/checkJsxChildrenProperty10.types new file mode 100644 index 0000000000000..cee5995b8515e --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty10.types @@ -0,0 +1,89 @@ +=== tests/cases/conformance/jsx/file.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface ElementAttributesProperty { props: {} } +>ElementAttributesProperty : ElementAttributesProperty +>props : {} + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + div: any; +>div : any + + h2: any; +>h2 : any + + h1: any; +>h1 : any + } +} + +class Button { +>Button : Button + + props: {} +>props : {} + + render() { +>render : () => JSX.Element + + return (
My Button
) +>(
My Button
) : JSX.Element +>
My Button
: JSX.Element +>div : any +>div : any + } +} + +// OK +let k1 =

Hello

world

; +>k1 : JSX.Element +>

Hello

world

: JSX.Element +>div : any +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>

world

: JSX.Element +>h1 : any +>h1 : any +>div : any + +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +>k2 : JSX.Element +>

Hello

{(user: any) =>

{user.name}

}
: JSX.Element +>div : any +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>(user: any) =>

{user.name}

: (user: any) => JSX.Element +>user : any +>

{user.name}

: JSX.Element +>h2 : any +>user.name : any +>user : any +>name : any +>h2 : any +>div : any + +let k3 =
{1} {"That is a number"}
; +>k3 : JSX.Element +>
{1} {"That is a number"}
: JSX.Element +>div : any +>1 : 1 +>"That is a number" : "That is a number" +>div : any + +let k4 = ; +>k4 : JSX.Element +> : JSX.Element +>Button : typeof Button +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>Button : typeof Button + diff --git a/tests/baselines/reference/checkJsxChildrenProperty11.js b/tests/baselines/reference/checkJsxChildrenProperty11.js new file mode 100644 index 0000000000000..f022b28f20c28 --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty11.js @@ -0,0 +1,38 @@ +//// [file.tsx] +declare module JSX { + interface Element { } + interface ElementAttributesProperty { props: {} } + interface IntrinsicElements { + div: any; + h2: any; + h1: any; + } +} + +class Button { + props: {} + render() { + return (
My Button
) + } +} + +// OK +let k1 =

Hello

world

; +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +let k3 =
{1} {"That is a number"}
; +let k4 = ; + +//// [file.jsx] +var Button = (function () { + function Button() { + } + Button.prototype.render = function () { + return (
My Button
); + }; + return Button; +}()); +// OK +var k1 =

Hello

world

; +var k2 =

Hello

{function (user) { return

{user.name}

; }}
; +var k3 =
{1} {"That is a number"}
; +var k4 = ; diff --git a/tests/baselines/reference/checkJsxChildrenProperty11.symbols b/tests/baselines/reference/checkJsxChildrenProperty11.symbols new file mode 100644 index 0000000000000..bf054377fb16a --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty11.symbols @@ -0,0 +1,73 @@ +=== 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 ElementAttributesProperty { props: {} } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(file.tsx, 1, 22)) +>props : Symbol(ElementAttributesProperty.props, Decl(file.tsx, 2, 38)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 50)) + + div: any; +>div : Symbol(IntrinsicElements.div, Decl(file.tsx, 3, 30)) + + h2: any; +>h2 : Symbol(IntrinsicElements.h2, Decl(file.tsx, 4, 11)) + + h1: any; +>h1 : Symbol(IntrinsicElements.h1, Decl(file.tsx, 5, 10)) + } +} + +class Button { +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) + + props: {} +>props : Symbol(Button.props, Decl(file.tsx, 10, 14)) + + render() { +>render : Symbol(Button.render, Decl(file.tsx, 11, 10)) + + return (
My Button
) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + } +} + +// OK +let k1 =

Hello

world

; +>k1 : Symbol(k1, Decl(file.tsx, 18, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(file.tsx, 5, 10)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(file.tsx, 5, 10)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +>k2 : Symbol(k2, Decl(file.tsx, 19, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>user : Symbol(user, Decl(file.tsx, 19, 34)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>user : Symbol(user, Decl(file.tsx, 19, 34)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k3 =
{1} {"That is a number"}
; +>k3 : Symbol(k3, Decl(file.tsx, 20, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(file.tsx, 3, 30)) + +let k4 = ; +>k4 : Symbol(k4, Decl(file.tsx, 21, 3)) +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(file.tsx, 4, 11)) +>Button : Symbol(Button, Decl(file.tsx, 8, 1)) + diff --git a/tests/baselines/reference/checkJsxChildrenProperty11.types b/tests/baselines/reference/checkJsxChildrenProperty11.types new file mode 100644 index 0000000000000..cee5995b8515e --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty11.types @@ -0,0 +1,89 @@ +=== tests/cases/conformance/jsx/file.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface ElementAttributesProperty { props: {} } +>ElementAttributesProperty : ElementAttributesProperty +>props : {} + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + div: any; +>div : any + + h2: any; +>h2 : any + + h1: any; +>h1 : any + } +} + +class Button { +>Button : Button + + props: {} +>props : {} + + render() { +>render : () => JSX.Element + + return (
My Button
) +>(
My Button
) : JSX.Element +>
My Button
: JSX.Element +>div : any +>div : any + } +} + +// OK +let k1 =

Hello

world

; +>k1 : JSX.Element +>

Hello

world

: JSX.Element +>div : any +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>

world

: JSX.Element +>h1 : any +>h1 : any +>div : any + +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +>k2 : JSX.Element +>

Hello

{(user: any) =>

{user.name}

}
: JSX.Element +>div : any +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>(user: any) =>

{user.name}

: (user: any) => JSX.Element +>user : any +>

{user.name}

: JSX.Element +>h2 : any +>user.name : any +>user : any +>name : any +>h2 : any +>div : any + +let k3 =
{1} {"That is a number"}
; +>k3 : JSX.Element +>
{1} {"That is a number"}
: JSX.Element +>div : any +>1 : 1 +>"That is a number" : "That is a number" +>div : any + +let k4 = ; +>k4 : JSX.Element +> : JSX.Element +>Button : typeof Button +>

Hello

: JSX.Element +>h2 : any +>h2 : any +>Button : typeof Button + diff --git a/tests/baselines/reference/checkJsxChildrenProperty3.symbols b/tests/baselines/reference/checkJsxChildrenProperty3.symbols index 2a1aca621e951..e2e8492156fb1 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty3.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty3.symbols @@ -61,11 +61,11 @@ function UserName0() { >user : Symbol(user, Decl(file.tsx, 22, 13))

{ user.Name }

->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) >user.Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) >user : Symbol(user, Decl(file.tsx, 22, 13)) >Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ) } @@ -85,11 +85,11 @@ function UserName1() { >user : Symbol(user, Decl(file.tsx, 33, 13))

{ user.Name }

->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) >user.Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) >user : Symbol(user, Decl(file.tsx, 33, 13)) >Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ) } diff --git a/tests/baselines/reference/checkJsxChildrenProperty6.symbols b/tests/baselines/reference/checkJsxChildrenProperty6.symbols index df48a53e37d05..7935b8cb2fe76 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty6.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty6.symbols @@ -29,8 +29,8 @@ class Button extends React.Component { >render : Symbol(Button.render, Decl(file.tsx, 8, 48)) return (
My Button
) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } @@ -39,8 +39,8 @@ function AnotherButton(p: any) { >p : Symbol(p, Decl(file.tsx, 14, 23)) return

Just Another Button

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) } function Comp(p: Prop) { @@ -49,11 +49,11 @@ function Comp(p: Prop) { >Prop : Symbol(Prop, Decl(file.tsx, 0, 32)) return
{p.b}
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 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, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } // Ok diff --git a/tests/baselines/reference/checkJsxChildrenProperty8.symbols b/tests/baselines/reference/checkJsxChildrenProperty8.symbols index 92c2e685e71c4..211009642bb53 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty8.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty8.symbols @@ -29,8 +29,8 @@ class Button extends React.Component { >render : Symbol(Button.render, Decl(file.tsx, 8, 48)) return (
My Button
) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } @@ -39,8 +39,8 @@ function AnotherButton(p: any) { >p : Symbol(p, Decl(file.tsx, 14, 23)) return

Just Another Button

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) } function Comp(p: Prop) { @@ -49,11 +49,11 @@ function Comp(p: Prop) { >Prop : Symbol(Prop, Decl(file.tsx, 0, 32)) return
{p.b}
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 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, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } // OK diff --git a/tests/baselines/reference/checkJsxChildrenProperty9.symbols b/tests/baselines/reference/checkJsxChildrenProperty9.symbols index 38f680a7aeba8..d37d8a1bfe656 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty9.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty9.symbols @@ -5,26 +5,26 @@ import React = require('react'); // OK let k1 =

Hello

world

; >k1 : Symbol(k1, Decl(file.tsx, 3, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) let k2 =

Hello

{(user: any) =>

{user.name}

}
; >k2 : Symbol(k2, Decl(file.tsx, 4, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) >user : Symbol(user, Decl(file.tsx, 4, 34)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) >user : Symbol(user, Decl(file.tsx, 4, 34)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2408, 48)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) let k3 =
{1} {"That is a number"}
; >k3 : Symbol(k3, Decl(file.tsx, 5, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols index 900aa7cf84225..fbe4d1bf5dc10 100644 --- a/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols +++ b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols @@ -19,8 +19,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 5, 50)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols index 766505b551812..15d4a04901f32 100644 --- a/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols +++ b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols @@ -19,8 +19,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 5, 50)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols index cc669b485e427..cb18cd27d624b 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols @@ -12,8 +12,8 @@ class Poisoned extends React.Component<{}, {}> { >render : Symbol(Poisoned.render, Decl(file.tsx, 2, 48)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols index f8c0bc4cf1f91..230e7b25dc5ae 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols @@ -48,8 +48,8 @@ class OverWriteAttr extends React.Component { >render : Symbol(OverWriteAttr.render, Decl(file.tsx, 17, 55)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols index ade152b687de4..c136d72444d0e 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols @@ -23,8 +23,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 7, 58)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols index c6b44bcd42859..6cb0486be61a1 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols @@ -23,8 +23,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 7, 58)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } @@ -56,8 +56,8 @@ class EmptyProp extends React.Component<{}, {}> { >render : Symbol(EmptyProp.render, Decl(file.tsx, 21, 49)) return
Default hi
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols index d3f967ca2e7d5..fd95004c914a1 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols @@ -22,8 +22,8 @@ class TextComponent extends React.Component { >render : Symbol(TextComponent.render, Decl(file.tsx, 5, 60)) return Some Text..; ->span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2458, 51)) ->span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2458, 51)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2462, 51)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2462, 51)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols index 6bfe0932173e6..1d0429a1cd154 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols @@ -45,8 +45,8 @@ class OverWriteAttr extends React.Component { >render : Symbol(OverWriteAttr.render, Decl(file.tsx, 17, 55)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols index ba9a28bfc1e41..26bda335e4fcf 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols @@ -23,8 +23,8 @@ class Opt extends React.Component { >render : Symbol(Opt.render, Decl(file.tsx, 7, 51)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols index a75b5f30c81e8..842c8b7b5d93a 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols @@ -5,7 +5,7 @@ import React = require('react'); const Foo = (props: any) =>
; >Foo : Symbol(Foo, Decl(file.tsx, 2, 5)) >props : Symbol(props, Decl(file.tsx, 2, 13)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) // Should be OK const foo = ; @@ -19,14 +19,14 @@ var MainMenu: React.StatelessComponent<{}> = (props) => (
>React : Symbol(React, Decl(file.tsx, 0, 0)) >StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) >props : Symbol(props, Decl(file.tsx, 8, 46)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45))

Main Menu

->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2409, 48)) ->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2409, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2413, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2413, 48))
); ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) var App: React.StatelessComponent<{ children }> = ({children}) => ( >App : Symbol(App, Decl(file.tsx, 12, 3)) @@ -36,12 +36,12 @@ var App: React.StatelessComponent<{ children }> = ({children}) => ( >children : Symbol(children, Decl(file.tsx, 12, 52))
->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) >MainMenu : Symbol(MainMenu, Decl(file.tsx, 8, 3))
->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ); diff --git a/tests/baselines/reference/tsxUnionElementType1.symbols b/tests/baselines/reference/tsxUnionElementType1.symbols index da0639ac5f15f..72b9d96dbe6aa 100644 --- a/tests/baselines/reference/tsxUnionElementType1.symbols +++ b/tests/baselines/reference/tsxUnionElementType1.symbols @@ -8,8 +8,8 @@ function SFC1(prop: { x: number }) { >x : Symbol(x, Decl(file.tsx, 2, 21)) return
hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) }; @@ -19,8 +19,8 @@ function SFC2(prop: { x: boolean }) { >x : Symbol(x, Decl(file.tsx, 6, 21)) return

World

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) } var SFCComp = SFC1 || SFC2; diff --git a/tests/baselines/reference/tsxUnionElementType5.symbols b/tests/baselines/reference/tsxUnionElementType5.symbols index e05f3deb9cca6..394e530231d6a 100644 --- a/tests/baselines/reference/tsxUnionElementType5.symbols +++ b/tests/baselines/reference/tsxUnionElementType5.symbols @@ -6,16 +6,16 @@ function EmptySFC1() { >EmptySFC1 : Symbol(EmptySFC1, Decl(file.tsx, 0, 32)) return
hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } function EmptySFC2() { >EmptySFC2 : Symbol(EmptySFC2, Decl(file.tsx, 4, 1)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) } function SFC2(prop: { x: boolean }) { @@ -24,8 +24,8 @@ function SFC2(prop: { x: boolean }) { >x : Symbol(x, Decl(file.tsx, 10, 21)) return

World

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2407, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) } var EmptySFCComp = EmptySFC1 || EmptySFC2; diff --git a/tests/baselines/reference/tsxUnionTypeComponent1.symbols b/tests/baselines/reference/tsxUnionTypeComponent1.symbols index ec57cfaa2de55..81ebe5ec01529 100644 --- a/tests/baselines/reference/tsxUnionTypeComponent1.symbols +++ b/tests/baselines/reference/tsxUnionTypeComponent1.symbols @@ -38,8 +38,8 @@ class MyComponent extends React.Component { }/> >MyComponent : Symbol(MyComponent, Decl(file.tsx, 4, 1)) >AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 14, 12)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2383, 43)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2383, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2387, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2387, 43)) // Component Class as Props class MyButtonComponent extends React.Component<{},{}> { diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty10.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty10.tsx new file mode 100644 index 0000000000000..f13f44567ffb4 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty10.tsx @@ -0,0 +1,24 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementAttributesProperty { props: {} } + interface IntrinsicElements { + div: any; + h2: any; + h1: any; + } +} + +class Button { + props: {} + render() { + return (
My Button
) + } +} + +// OK +let k1 =

Hello

world

; +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +let k3 =
{1} {"That is a number"}
; +let k4 = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty11.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty11.tsx new file mode 100644 index 0000000000000..a6fab6f506e66 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty11.tsx @@ -0,0 +1,25 @@ +//@filename: file.tsx +//@jsx: preserve +//@noImplicitAny: true +declare module JSX { + interface Element { } + interface ElementAttributesProperty { props: {} } + interface IntrinsicElements { + div: any; + h2: any; + h1: any; + } +} + +class Button { + props: {} + render() { + return (
My Button
) + } +} + +// OK +let k1 =

Hello

world

; +let k2 =

Hello

{(user: any) =>

{user.name}

}
; +let k3 =
{1} {"That is a number"}
; +let k4 = ; \ No newline at end of file diff --git a/tests/cases/fourslash/tscCompletionInFunctionExpressionOfChildrenCallback.ts b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback.ts similarity index 89% rename from tests/cases/fourslash/tscCompletionInFunctionExpressionOfChildrenCallback.ts rename to tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback.ts index 0a926e64ac0ed..911fa41470dc8 100644 --- a/tests/cases/fourslash/tscCompletionInFunctionExpressionOfChildrenCallback.ts +++ b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback.ts @@ -27,5 +27,4 @@ //// } goTo.marker(); -debugger; -verify.completionListContains('Name'); \ No newline at end of file +verify.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts new file mode 100644 index 0000000000000..491188115ebbb --- /dev/null +++ b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts @@ -0,0 +1,32 @@ +/// +//@module: commonjs +//@jsx: preserve + +// @Filename: 1.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { +//// props: { children; } +//// } +//// } +//// interface IUser { +//// Name: string; +//// } +//// interface IFetchUserProps { +//// children: (user: IUser) => any; +//// } +//// function FetchUser(props: IFetchUserProps) { return undefined; } +//// function UserName() { +//// return ( +//// +//// { user => ( +////

{ user./**/ }

+//// )} +////
+//// ); +//// } + +goTo.marker(); +verify.completionListContains('Name'); \ No newline at end of file From 7829cbae26ea1ccf6531c9958746f04b75595399 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 17 Apr 2017 13:00:45 -0700 Subject: [PATCH 16/22] Fix linting error --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 712b77ab3355b..c5b531337c93a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -411,7 +411,7 @@ namespace ts { let _jsxNamespace: string; let _jsxFactoryEntity: EntityName; - let _jsxElementAttribPropInterfaceSymbol: Symbol; // JSX.ElementAttributesProperty [symbol] + let _jsxElementAttribPropInterfaceSymbol: Symbol; // JSX.ElementAttributesProperty [symbol] let _jsxElementPropertiesName: string; let _jsxElementChildrenPropertyName: string; @@ -13506,7 +13506,7 @@ namespace ts { const propsType = getTypeOfSymbol(propertiesOfJsxElementAttribPropInterface[0]); const propertiesOfProps = propsType && getPropertiesOfType(propsType); if (propertiesOfProps && propertiesOfProps.length === 1) { - _jsxElementChildrenPropertyName = propertiesOfProps[0].name; + _jsxElementChildrenPropertyName = propertiesOfProps[0].name; } } } From d290cf7633d2d05300ff7332decff7de095b4eab Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 17 Apr 2017 13:11:16 -0700 Subject: [PATCH 17/22] Update error message to use variable name for "children" --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../reference/checkJsxChildrenProperty2.errors.txt | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c5b531337c93a..95b3de8df40d8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13322,7 +13322,7 @@ namespace ts { const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); if (jsxChildrenPropertyName) { if (attributesTable.has(jsxChildrenPropertyName)) { - error(attributes, Diagnostics.props_children_are_specified_twice_The_attribute_named_children_will_be_overwritten); + error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, jsxChildrenPropertyName); } // If there are children in the body of JSX element, create dummy attribute "children" with anyType so that it will pass the attribute checking process diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 72554a9f0bacf..b7f30e2b209c8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2099,7 +2099,7 @@ "category": "Error", "code": 2707 }, - "props.children are specified twice. The attribute named 'children' will be overwritten.": { + "'{0}' are specified twice. The attribute named '{0}' will be overwritten.": { "category": "Error", "code": 2708 }, diff --git a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt index ecde87c6fbf6e..d288d92e93bc9 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt @@ -1,8 +1,8 @@ tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'. Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'. Property 'children' is missing in type '{ a: 10; b: "hi"; }'. -tests/cases/conformance/jsx/file.tsx(17,11): error TS2708: props.children are specified twice. The attribute named 'children' will be overwritten. -tests/cases/conformance/jsx/file.tsx(25,11): error TS2708: props.children are specified twice. The attribute named 'children' will be overwritten. +tests/cases/conformance/jsx/file.tsx(17,11): error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. +tests/cases/conformance/jsx/file.tsx(25,11): error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. tests/cases/conformance/jsx/file.tsx(31,11): error TS2322: Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'. Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'. Types of property 'children' are incompatible. @@ -52,7 +52,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi let k0 = ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2708: props.children are specified twice. The attribute named 'children' will be overwritten. +!!! error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. hi hi hi! ; @@ -62,7 +62,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi let k1 = ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2708: props.children are specified twice. The attribute named 'children' will be overwritten. +!!! error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. hi hi hi! ; From c13383a3a36e0b485dda8a3b5949f18317aa7beb Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 17 Apr 2017 13:32:57 -0700 Subject: [PATCH 18/22] Fix baselines and linting error from merging with master --- src/compiler/checker.ts | 6 +++--- .../reference/checkJsxChildrenProperty2.errors.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb62dff01c13f..9f623abec5fd9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8696,10 +8696,10 @@ namespace ts { // type, a property is considered known if it is known in any constituent type. function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean): boolean { if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); + const resolved = resolveStructuredTypeMembers(type); if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) || getPropertyOfType(type, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { - // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. + // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. return true; } } @@ -13477,7 +13477,7 @@ namespace ts { function getPropertiesFromJsxElementAttributesProperty() { if (!_jsxElementAttribPropInterfaceSymbol) { // JSX - const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/undefined); + const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); // JSX.ElementAttributesProperty [symbol] _jsxElementAttribPropInterfaceSymbol = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, SymbolFlags.Type); } diff --git a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt index d288d92e93bc9..6bb91bd638501 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt @@ -1,8 +1,8 @@ tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & Prop'. Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'. Property 'children' is missing in type '{ a: 10; b: "hi"; }'. -tests/cases/conformance/jsx/file.tsx(17,11): error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. -tests/cases/conformance/jsx/file.tsx(25,11): error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. +tests/cases/conformance/jsx/file.tsx(17,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. +tests/cases/conformance/jsx/file.tsx(25,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. tests/cases/conformance/jsx/file.tsx(31,11): error TS2322: Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'. Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'. Types of property 'children' are incompatible. @@ -52,7 +52,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi let k0 = ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. +!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. hi hi hi! ; @@ -62,7 +62,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi let k1 = ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2708: 'children' are specified twice. The attribute named 'children' will be overwritten. +!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. hi hi hi! ; From e9cd3ade8600527b7ed9f1b13a514e5b61048580 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Apr 2017 22:33:33 -0700 Subject: [PATCH 19/22] Change how we look up children attribute from react.d.ts --- src/compiler/checker.ts | 103 +++++++++++++++------------------------- tests/lib/react.d.ts | 8 ++-- 2 files changed, 42 insertions(+), 69 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9f623abec5fd9..0524c24a70047 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -423,17 +423,20 @@ namespace ts { let _jsxNamespace: string; let _jsxFactoryEntity: EntityName; - let _jsxElementAttribPropInterfaceSymbol: Symbol; // JSX.ElementAttributesProperty [symbol] let _jsxElementPropertiesName: string; + let _hasComputedJsxElementPropertiesName = false; let _jsxElementChildrenPropertyName: string; + let _hasComputedJsxElementChildrenPropertyName = false; /** Things we lazy load from the JSX namespace */ const jsxTypes = createMap(); + const JsxNames = { JSX: "JSX", IntrinsicElements: "IntrinsicElements", ElementClass: "ElementClass", ElementAttributesPropertyNameContainer: "ElementAttributesProperty", + ElementChildrenAttributeNameContainer: "ElementChildrenAttribute", Element: "Element", IntrinsicAttributes: "IntrinsicAttributes", IntrinsicClassAttributes: "IntrinsicClassAttributes" @@ -12696,7 +12699,7 @@ namespace ts { else if (node.parent.kind === SyntaxKind.JsxElement) { // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty) const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); - return jsxChildrenPropertyName ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType; + return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType; } else { // JSX expression is in JSX spread attribute @@ -13361,7 +13364,7 @@ namespace ts { // Error if there is a attribute named "children" and children element. // This is because children element will overwrite the value from attributes const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); - if (jsxChildrenPropertyName) { + if (jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { if (attributesTable.has(jsxChildrenPropertyName)) { error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, jsxChildrenPropertyName); } @@ -13474,14 +13477,34 @@ namespace ts { return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); } - function getPropertiesFromJsxElementAttributesProperty() { - if (!_jsxElementAttribPropInterfaceSymbol) { - // JSX - const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); - // JSX.ElementAttributesProperty [symbol] - _jsxElementAttribPropInterfaceSymbol = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, SymbolFlags.Type); + /** + * + */ + function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: string): string { + // JSX + const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); + // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol] + const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, SymbolFlags.Type); + // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type] + const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym); + // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute + const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType); + if (propertiesOfJsxElementAttribPropInterface) { + // Element Attributes has zero properties, so the element attributes type will be the class instance type + if (propertiesOfJsxElementAttribPropInterface.length === 0) { + return ""; + } + // Element Attributes has one property, so the element attributes type will be the type of the corresponding + // property of the class instance type + else if (propertiesOfJsxElementAttribPropInterface.length === 1) { + return propertiesOfJsxElementAttribPropInterface[0].name; + } + else if (propertiesOfJsxElementAttribPropInterface.length > 1) { + // More than one property on ElementAttributesProperty is an error + error(jsxElementAttribPropInterfaceSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, nameOfAttribPropContainer); + } } - return _jsxElementAttribPropInterfaceSymbol; + return undefined; } /// e.g. "props" for React.d.ts, @@ -13490,66 +13513,18 @@ namespace ts { /// or '' if it has 0 properties (which means every /// non-intrinsic elements' attributes type is the element instance type) function getJsxElementPropertiesName() { - if (!_jsxElementPropertiesName) { - const jsxElementAttribPropInterfaceSym = getPropertiesFromJsxElementAttributesProperty(); - // JSX.ElementAttributesProperty [type] - const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym); - // The properties of JSX.ElementAttributesProperty - const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType); - - // if there is a property in JSX.ElementAttributesProperty - // i.e. - // interface ElementAttributesProperty { - // props: { - // children?: any; - // }; - // } - if (propertiesOfJsxElementAttribPropInterface) { - // Element Attributes has zero properties, so the element attributes type will be the class instance type - if (propertiesOfJsxElementAttribPropInterface.length === 0) { - _jsxElementPropertiesName = ""; - } - // Element Attributes has one property, so the element attributes type will be the type of the corresponding - // property of the class instance type - else if (propertiesOfJsxElementAttribPropInterface.length === 1) { - _jsxElementPropertiesName = propertiesOfJsxElementAttribPropInterface[0].name; - } - // More than one property on ElementAttributesProperty is an error - else { - error(jsxElementAttribPropInterfaceSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, JsxNames.ElementAttributesPropertyNameContainer); - _jsxElementPropertiesName = undefined; - } - } - else { - // No interface exists, so the element attributes type will be an implicit any - _jsxElementPropertiesName = undefined; - } + if (!_hasComputedJsxElementPropertiesName) { + _hasComputedJsxElementPropertiesName = true; + _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer); } return _jsxElementPropertiesName; } function getJsxElementChildrenPropertyname(): string { - if (!_jsxElementChildrenPropertyName) { - const jsxElementAttribPropInterfaceSym = getPropertiesFromJsxElementAttributesProperty(); - // JSX.ElementAttributesProperty [type] - const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym); - // The properties of JSX.ElementAttributesProperty - const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType); - // if there is a property in JSX.ElementAttributesProperty - // i.e. - // interface ElementAttributesProperty { - // props: { - // children?: any; - // }; - // } - if (propertiesOfJsxElementAttribPropInterface && propertiesOfJsxElementAttribPropInterface.length === 1) { - const propsType = getTypeOfSymbol(propertiesOfJsxElementAttribPropInterface[0]); - const propertiesOfProps = propsType && getPropertiesOfType(propsType); - if (propertiesOfProps && propertiesOfProps.length === 1) { - _jsxElementChildrenPropertyName = propertiesOfProps[0].name; - } - } + if (!_hasComputedJsxElementChildrenPropertyName) { + _hasComputedJsxElementChildrenPropertyName = true; + _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer); } return _jsxElementChildrenPropertyName; diff --git a/tests/lib/react.d.ts b/tests/lib/react.d.ts index cb34c8ab38f9b..0629cb956fc9b 100644 --- a/tests/lib/react.d.ts +++ b/tests/lib/react.d.ts @@ -2359,11 +2359,9 @@ declare namespace JSX { interface ElementClass extends React.Component { render(): JSX.Element | null; } - interface ElementAttributesProperty { - props: { - children: any; - }; - } + interface ElementAttributesProperty { props; } + + interface ElementChildrenAttribute { children; } interface IntrinsicAttributes extends React.Attributes { } From b7a30c11bd321a1c59c6d902caf4f5c145984be5 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Apr 2017 22:33:54 -0700 Subject: [PATCH 20/22] Update tests and baselines --- .../checkJsxChildrenProperty1.symbols | 8 +++--- .../checkJsxChildrenProperty3.symbols | 8 +++--- .../checkJsxChildrenProperty6.symbols | 12 ++++---- .../checkJsxChildrenProperty8.symbols | 12 ++++---- .../checkJsxChildrenProperty9.symbols | 28 +++++++++---------- .../tsxDefaultAttributesResolution1.symbols | 4 +-- .../tsxDefaultAttributesResolution2.symbols | 4 +-- .../tsxSpreadAttributesResolution1.symbols | 4 +-- .../tsxSpreadAttributesResolution11.symbols | 4 +-- .../tsxSpreadAttributesResolution3.symbols | 4 +-- .../tsxSpreadAttributesResolution4.symbols | 8 +++--- .../tsxSpreadAttributesResolution7.symbols | 4 +-- .../tsxSpreadAttributesResolution8.symbols | 4 +-- .../tsxSpreadAttributesResolution9.symbols | 4 +-- .../tsxStatelessFunctionComponents3.symbols | 14 +++++----- .../reference/tsxUnionElementType1.symbols | 8 +++--- .../reference/tsxUnionElementType5.symbols | 12 ++++---- .../reference/tsxUnionTypeComponent1.symbols | 4 +-- ...InFunctionExpressionOfChildrenCallback1.ts | 5 ++-- 19 files changed, 75 insertions(+), 76 deletions(-) diff --git a/tests/baselines/reference/checkJsxChildrenProperty1.symbols b/tests/baselines/reference/checkJsxChildrenProperty1.symbols index d80a3b1e82b5f..8793d0edd496d 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty1.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty1.symbols @@ -23,11 +23,11 @@ function Comp(p: Prop) { >Prop : Symbol(Prop, Decl(file.tsx, 0, 32)) return
{p.b}
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) >p.b : Symbol(Prop.b, Decl(file.tsx, 3, 14)) >p : Symbol(p, Decl(file.tsx, 8, 14)) >b : Symbol(Prop.b, Decl(file.tsx, 3, 14)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } // OK @@ -59,8 +59,8 @@ let k2 = >b : Symbol(b, Decl(file.tsx, 19, 16))
hi hi hi!
->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) ; >Comp : Symbol(Comp, Decl(file.tsx, 6, 1)) diff --git a/tests/baselines/reference/checkJsxChildrenProperty3.symbols b/tests/baselines/reference/checkJsxChildrenProperty3.symbols index e2e8492156fb1..49d146f07dac4 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty3.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty3.symbols @@ -61,11 +61,11 @@ function UserName0() { >user : Symbol(user, Decl(file.tsx, 22, 13))

{ user.Name }

->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) >user.Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) >user : Symbol(user, Decl(file.tsx, 22, 13)) >Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) ) } @@ -85,11 +85,11 @@ function UserName1() { >user : Symbol(user, Decl(file.tsx, 33, 13))

{ user.Name }

->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) >user.Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) >user : Symbol(user, Decl(file.tsx, 33, 13)) >Name : Symbol(IUser.Name, Decl(file.tsx, 2, 17)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) ) } diff --git a/tests/baselines/reference/checkJsxChildrenProperty6.symbols b/tests/baselines/reference/checkJsxChildrenProperty6.symbols index 7935b8cb2fe76..e69b24a89ab22 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty6.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty6.symbols @@ -29,8 +29,8 @@ class Button extends React.Component { >render : Symbol(Button.render, Decl(file.tsx, 8, 48)) return (
My Button
) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } @@ -39,8 +39,8 @@ function AnotherButton(p: any) { >p : Symbol(p, Decl(file.tsx, 14, 23)) return

Just Another Button

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) } function Comp(p: Prop) { @@ -49,11 +49,11 @@ function Comp(p: Prop) { >Prop : Symbol(Prop, Decl(file.tsx, 0, 32)) return
{p.b}
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 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, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } // Ok diff --git a/tests/baselines/reference/checkJsxChildrenProperty8.symbols b/tests/baselines/reference/checkJsxChildrenProperty8.symbols index 211009642bb53..b6f5f97adac23 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty8.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty8.symbols @@ -29,8 +29,8 @@ class Button extends React.Component { >render : Symbol(Button.render, Decl(file.tsx, 8, 48)) return (
My Button
) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } @@ -39,8 +39,8 @@ function AnotherButton(p: any) { >p : Symbol(p, Decl(file.tsx, 14, 23)) return

Just Another Button

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) } function Comp(p: Prop) { @@ -49,11 +49,11 @@ function Comp(p: Prop) { >Prop : Symbol(Prop, Decl(file.tsx, 0, 32)) return
{p.b}
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 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, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } // OK diff --git a/tests/baselines/reference/checkJsxChildrenProperty9.symbols b/tests/baselines/reference/checkJsxChildrenProperty9.symbols index d37d8a1bfe656..25a32aae695f8 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty9.symbols +++ b/tests/baselines/reference/checkJsxChildrenProperty9.symbols @@ -5,26 +5,26 @@ import React = require('react'); // OK let k1 =

Hello

world

; >k1 : Symbol(k1, Decl(file.tsx, 3, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) let k2 =

Hello

{(user: any) =>

{user.name}

}
; >k2 : Symbol(k2, Decl(file.tsx, 4, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) >user : Symbol(user, Decl(file.tsx, 4, 34)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) >user : Symbol(user, Decl(file.tsx, 4, 34)) ->h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2412, 48)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>h2 : Symbol(JSX.IntrinsicElements.h2, Decl(react.d.ts, 2410, 48)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) let k3 =
{1} {"That is a number"}
; >k3 : Symbol(k3, Decl(file.tsx, 5, 3)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols index fbe4d1bf5dc10..ff8926b0ab0c8 100644 --- a/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols +++ b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols @@ -19,8 +19,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 5, 50)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols index 15d4a04901f32..61d007ddbefa3 100644 --- a/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols +++ b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols @@ -19,8 +19,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 5, 50)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols index cb18cd27d624b..273ea39281aed 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols @@ -12,8 +12,8 @@ class Poisoned extends React.Component<{}, {}> { >render : Symbol(Poisoned.render, Decl(file.tsx, 2, 48)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols index 230e7b25dc5ae..5646934ef4155 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols @@ -48,8 +48,8 @@ class OverWriteAttr extends React.Component { >render : Symbol(OverWriteAttr.render, Decl(file.tsx, 17, 55)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols index c136d72444d0e..05de039a49a68 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols @@ -23,8 +23,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 7, 58)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols index 6cb0486be61a1..93d8535658e8c 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols @@ -23,8 +23,8 @@ class Poisoned extends React.Component { >render : Symbol(Poisoned.render, Decl(file.tsx, 7, 58)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } @@ -56,8 +56,8 @@ class EmptyProp extends React.Component<{}, {}> { >render : Symbol(EmptyProp.render, Decl(file.tsx, 21, 49)) return
Default hi
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols index fd95004c914a1..8a6e3fd317b2e 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols @@ -22,8 +22,8 @@ class TextComponent extends React.Component { >render : Symbol(TextComponent.render, Decl(file.tsx, 5, 60)) return Some Text..; ->span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2462, 51)) ->span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2462, 51)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols index 1d0429a1cd154..2dec493b88676 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols @@ -45,8 +45,8 @@ class OverWriteAttr extends React.Component { >render : Symbol(OverWriteAttr.render, Decl(file.tsx, 17, 55)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols index 26bda335e4fcf..f55b20dfe64c4 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols @@ -23,8 +23,8 @@ class Opt extends React.Component { >render : Symbol(Opt.render, Decl(file.tsx, 7, 51)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols index 842c8b7b5d93a..a18da7954bc56 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols @@ -5,7 +5,7 @@ import React = require('react'); const Foo = (props: any) =>
; >Foo : Symbol(Foo, Decl(file.tsx, 2, 5)) >props : Symbol(props, Decl(file.tsx, 2, 13)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) // Should be OK const foo = ; @@ -19,14 +19,14 @@ var MainMenu: React.StatelessComponent<{}> = (props) => (
>React : Symbol(React, Decl(file.tsx, 0, 0)) >StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) >props : Symbol(props, Decl(file.tsx, 8, 46)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45))

Main Menu

->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2413, 48)) ->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2413, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2411, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2411, 48))
); ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) var App: React.StatelessComponent<{ children }> = ({children}) => ( >App : Symbol(App, Decl(file.tsx, 12, 3)) @@ -36,12 +36,12 @@ var App: React.StatelessComponent<{ children }> = ({children}) => ( >children : Symbol(children, Decl(file.tsx, 12, 52))
->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) >MainMenu : Symbol(MainMenu, Decl(file.tsx, 8, 3))
->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) ); diff --git a/tests/baselines/reference/tsxUnionElementType1.symbols b/tests/baselines/reference/tsxUnionElementType1.symbols index 72b9d96dbe6aa..728e559ee65d8 100644 --- a/tests/baselines/reference/tsxUnionElementType1.symbols +++ b/tests/baselines/reference/tsxUnionElementType1.symbols @@ -8,8 +8,8 @@ function SFC1(prop: { x: number }) { >x : Symbol(x, Decl(file.tsx, 2, 21)) return
hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) }; @@ -19,8 +19,8 @@ function SFC2(prop: { x: boolean }) { >x : Symbol(x, Decl(file.tsx, 6, 21)) return

World

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) } var SFCComp = SFC1 || SFC2; diff --git a/tests/baselines/reference/tsxUnionElementType5.symbols b/tests/baselines/reference/tsxUnionElementType5.symbols index 394e530231d6a..9a5e94f69a319 100644 --- a/tests/baselines/reference/tsxUnionElementType5.symbols +++ b/tests/baselines/reference/tsxUnionElementType5.symbols @@ -6,16 +6,16 @@ function EmptySFC1() { >EmptySFC1 : Symbol(EmptySFC1, Decl(file.tsx, 0, 32)) return
hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } function EmptySFC2() { >EmptySFC2 : Symbol(EmptySFC2, Decl(file.tsx, 4, 1)) return
Hello
; ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2401, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) } function SFC2(prop: { x: boolean }) { @@ -24,8 +24,8 @@ function SFC2(prop: { x: boolean }) { >x : Symbol(x, Decl(file.tsx, 10, 21)) return

World

; ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) ->h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2411, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) +>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(react.d.ts, 2409, 47)) } var EmptySFCComp = EmptySFC1 || EmptySFC2; diff --git a/tests/baselines/reference/tsxUnionTypeComponent1.symbols b/tests/baselines/reference/tsxUnionTypeComponent1.symbols index 81ebe5ec01529..4af712bf3fc3e 100644 --- a/tests/baselines/reference/tsxUnionTypeComponent1.symbols +++ b/tests/baselines/reference/tsxUnionTypeComponent1.symbols @@ -38,8 +38,8 @@ class MyComponent extends React.Component { }/> >MyComponent : Symbol(MyComponent, Decl(file.tsx, 4, 1)) >AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 14, 12)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2387, 43)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2387, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2385, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2385, 43)) // Component Class as Props class MyButtonComponent extends React.Component<{},{}> { diff --git a/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts index 491188115ebbb..d849948775e62 100644 --- a/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts +++ b/tests/cases/fourslash/tsxCompletionInFunctionExpressionOfChildrenCallback1.ts @@ -7,9 +7,8 @@ //// interface Element { } //// interface IntrinsicElements { //// } -//// interface ElementAttributesProperty { -//// props: { children; } -//// } +//// interface ElementAttributesProperty { props; } +//// interface ElementChildrenAttribute { children; } //// } //// interface IUser { //// Name: string; From e03be4518265c6ff08a6f16e3c73fbb4772e418e Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 19 Apr 2017 22:42:07 -0700 Subject: [PATCH 21/22] Fix spelling and add comment --- src/compiler/checker.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0524c24a70047..e7939967a4b75 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13478,8 +13478,12 @@ namespace ts { } /** + * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer. + * Get a single property from that container if existed. Report an error if there are more than one property. * - */ + * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer + * if other string is given or the container doesn't exist, return undefined. + **/ function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: string): string { // JSX const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); @@ -14647,7 +14651,7 @@ namespace ts { // We can figure that out by resolving attributes property and check number of properties in the resolved type // If the call has correct arity, we will then check if the argument type and parameter type is assignable - const callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incoplete + const callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incomplete if (callIsIncomplete) { return true; } From e7e13ecbfcd5207073cc1ff2b57cbd05ea84b9b0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Fri, 21 Apr 2017 09:42:19 -0700 Subject: [PATCH 22/22] Fix linting --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e7939967a4b75..ff58a4e67ae8e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13477,13 +13477,13 @@ namespace ts { return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); } - /** + /** * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer. * Get a single property from that container if existed. Report an error if there are more than one property. - * + * * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer * if other string is given or the container doesn't exist, return undefined. - **/ + */ function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: string): string { // JSX const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);