From 7d02df80cea129d10ad23fc4269b30b8807c50ae Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 7 Nov 2016 17:01:04 -0800 Subject: [PATCH 01/25] Parse JSX attributes as its own unique AST node and bind the node --- src/compiler/binder.ts | 17 +++++++++++++++++ src/compiler/parser.ts | 12 ++++++++++-- src/compiler/types.ts | 37 +++++++++++++++++++++++-------------- src/compiler/utilities.ts | 15 +++++++++++++++ 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 00d409aecf014..5b83017429979 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1299,6 +1299,7 @@ namespace ts { case SyntaxKind.TypeLiteral: case SyntaxKind.JSDocTypeLiteral: case SyntaxKind.JSDocRecordType: + case SyntaxKind.JsxAttributes: return ContainerFlags.IsContainer; case SyntaxKind.InterfaceDeclaration: @@ -1404,6 +1405,7 @@ namespace ts { case SyntaxKind.InterfaceDeclaration: case SyntaxKind.JSDocRecordType: case SyntaxKind.JSDocTypeLiteral: + case SyntaxKind.JsxAttributes: // Interface/Object-types always have their children added to the 'members' of // their container. They are only accessible through an instance of their // container, and are never in scope otherwise (even inside the body of the @@ -1587,6 +1589,14 @@ namespace ts { return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); } + function bindJsxAttributes(node: JsxAttributes) { + return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes"); + } + + function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); + } + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { const symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); @@ -1996,6 +2006,12 @@ namespace ts { case SyntaxKind.ModuleDeclaration: return bindModuleDeclaration(node); + // Jsx-attributes + case SyntaxKind.JsxAttributes: + return bindJsxAttributes(node); + case SyntaxKind.JsxAttribute: + return bindJsxAttribute(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + // Imports and exports case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: @@ -3052,6 +3068,7 @@ namespace ts { case SyntaxKind.JsxText: case SyntaxKind.JsxClosingElement: case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxAttributes: case SyntaxKind.JsxSpreadAttribute: case SyntaxKind.JsxExpression: // These nodes are Jsx syntax. diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9e0a5b4cd3379..83773f8fe263b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -361,7 +361,9 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: return visitNode(cbNode, (node).tagName) || - visitNodes(cbNodes, (node).attributes); + visitNode(cbNode, (node).attributes); + case SyntaxKind.JsxAttributes: + return visitNodes(cbNodes, (node).properties); case SyntaxKind.JsxAttribute: return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).initializer); @@ -3795,14 +3797,20 @@ namespace ts { return result; } + function parseJsxAttributes(): JsxAttributes { + const jsxAttributes = createNode(SyntaxKind.JsxAttributes); + jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute); + return finishNode(jsxAttributes); + } + function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement { const fullStart = scanner.getStartPos(); parseExpected(SyntaxKind.LessThanToken); const tagName = parseJsxElementName(); + const attributes = parseJsxAttributes(); - const attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute); let node: JsxOpeningLikeElement; if (token() === SyntaxKind.GreaterThanToken) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 61bbff691bc05..d0ef8ab714fde 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -308,6 +308,7 @@ namespace ts { JsxOpeningElement, JsxClosingElement, JsxAttribute, + JsxAttributes, JsxSpreadAttribute, JsxExpression, @@ -704,6 +705,7 @@ namespace ts { // SyntaxKind.BindingElement // SyntaxKind.Property // SyntaxKind.PropertyAssignment + // SyntaxKind.JsxAttribute // SyntaxKind.ShorthandPropertyAssignment // SyntaxKind.EnumMember // SyntaxKind.JSDocPropertyTag @@ -1372,7 +1374,7 @@ namespace ts { template: TemplateLiteral; } - export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; + export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; export interface AsExpression extends Expression { kind: SyntaxKind.AsExpression; @@ -1401,35 +1403,39 @@ namespace ts { closingElement: JsxClosingElement; } + /// Either the opening tag in a ... pair, or the lone in a self-closing form + export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + + export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; + export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression; + export interface JsxAttributes extends ObjectLiteralExpressionBase { + } + /// The opening element of a ... JsxElement export interface JsxOpeningElement extends Expression { kind: SyntaxKind.JsxOpeningElement; tagName: JsxTagNameExpression; - attributes: NodeArray; + attributes: JsxAttributes; } /// A JSX expression of the form export interface JsxSelfClosingElement extends PrimaryExpression { kind: SyntaxKind.JsxSelfClosingElement; tagName: JsxTagNameExpression; - attributes: NodeArray; + attributes: JsxAttributes; } - /// Either the opening tag in a ... pair, or the lone in a self-closing form - export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; - - export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; - - export interface JsxAttribute extends Node { - kind: SyntaxKind.JsxAttribute; + // @kind(SyntaxKind.JsxAttribute) + export interface JsxAttribute extends ObjectLiteralElement { name: Identifier; /// JSX attribute initializers are optional; is sugar for initializer?: StringLiteral | JsxExpression; } - export interface JsxSpreadAttribute extends Node { + // @kind(SyntaxKind.JsxSpreadAttribute) + export interface JsxSpreadAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxSpreadAttribute; expression: Expression; } @@ -2297,7 +2303,7 @@ namespace ts { getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; - getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; + getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type; getJsxIntrinsicTagNames(): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; @@ -2590,6 +2596,7 @@ namespace ts { /* @internal */ isReferenced?: boolean; // True if the symbol is referenced elsewhere /* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol? /* @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments + /* @internal */ syntheticKind?: SyntheticSymbolKind; // Synthetic symbols are either spread or union/intersection } /* @internal */ @@ -2669,7 +2676,7 @@ namespace ts { isVisible?: boolean; // Is this node visible hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with - resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element + resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing switchTypes?: Type[]; // Cached array of switch case expression types @@ -2704,6 +2711,8 @@ namespace ts { ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type /* @internal */ ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type + /* @internal */ + JsxAttributes = 1 << 24, // Jsx attributes type /* @internal */ Nullable = Undefined | Null, @@ -2866,7 +2875,7 @@ namespace ts { /* @internal */ // Object literals are initially marked fresh. Freshness disappears following an assignment, - // before a type assertion, or when when an object literal's type is widened. The regular + // before a type assertion, or when an object literal's type is widened. The regular // version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag. export interface FreshObjectLiteralType extends ResolvedType { regularType: ResolvedType; // Regular version of fresh type diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 53a4ad33f3400..7d902ab4e0a87 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1073,6 +1073,8 @@ namespace ts { export function isCallLikeExpression(node: Node): node is CallLikeExpression { switch (node.kind) { + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.TaggedTemplateExpression: @@ -1087,6 +1089,9 @@ namespace ts { if (node.kind === SyntaxKind.TaggedTemplateExpression) { return (node).tag; } + else if (isJsxOpeningLikeElement(node)) { + return node.tagName; + } // Will either be a CallExpression, NewExpression, or Decorator. return (node).expression; @@ -4132,6 +4137,7 @@ namespace ts { || kind === SyntaxKind.ImportEqualsDeclaration || kind === SyntaxKind.ImportSpecifier || kind === SyntaxKind.InterfaceDeclaration + || kind === SyntaxKind.JsxAttribute || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.ModuleDeclaration @@ -4244,6 +4250,11 @@ namespace ts { || kind === SyntaxKind.JsxText; } + export function isJsxAttributes(node: Node): node is JsxAttributes { + const kind = node.kind; + return kind === SyntaxKind.JsxAttributes; + } + export function isJsxAttributeLike(node: Node): node is JsxAttributeLike { const kind = node.kind; return kind === SyntaxKind.JsxAttribute @@ -4258,6 +4269,10 @@ namespace ts { return node.kind === SyntaxKind.JsxAttribute; } + export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement { + return node.kind === SyntaxKind.JsxOpeningElement || node.kind === SyntaxKind.JsxSelfClosingElement; + } + export function isStringLiteralOrJsxExpression(node: Node): node is StringLiteral | JsxExpression { const kind = node.kind; return kind === SyntaxKind.StringLiteral From 2eeabeb5398e3a515deb4234818bbd7af7a27c53 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 08:45:44 -0800 Subject: [PATCH 02/25] Use chooseOverload logic to pick JSX stateless function --- src/compiler/checker.ts | 665 ++++++++++++++++++++++++++++++---------- 1 file changed, 505 insertions(+), 160 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8ac6b0f647190..98c5837606982 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -105,7 +105,7 @@ namespace ts { getExportsOfModule: getExportsOfModuleAsArray, getAmbientModules, - getJsxElementAttributesType, + getAllAttributesTypeFromJsxOpeningLikeElement, getJsxIntrinsicTagNames, isOptionalParameter, tryFindAmbientModuleWithoutAugmentations: moduleName => { @@ -557,7 +557,7 @@ namespace ts { return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(node); } - function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol { + function getSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags): Symbol { if (meaning) { const symbol = symbols[name]; if (symbol) { @@ -3212,6 +3212,11 @@ namespace ts { const type = checkDeclarationInitializer(declaration); return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality); } + else if (isJsxAttribute(declaration)) { + // For JSX Attribute, if it doesn't have initializer, by default the attribute gets true-type. + // is sugar for + return trueType; + } // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === SyntaxKind.ShorthandPropertyAssignment) { @@ -6997,19 +7002,24 @@ 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): boolean { + function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean): boolean { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); - if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) || - resolved.stringIndexInfo || - (resolved.numberIndexInfo && isNumericLiteralName(name)) || - getPropertyOfType(type, name)) { + if ((relation === assignableRelation || relation === comparableRelation) && + (type === globalObjectType || isEmptyObjectType(resolved))) { + return true; + } + else if (resolved.stringIndexInfo || (resolved.numberIndexInfo && isNumericLiteralName(name))) { + return true; + } + else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) { + // For JSXAttributes, if the attribute has hyphenated name considered the attribute to be known return true; } } else if (type.flags & TypeFlags.UnionOrIntersection) { for (const t of (type).types) { - if (isKnownProperty(t, name)) { + if (isKnownProperty(t, name, isComparingJsxAttributes)) { return true; } } @@ -7027,16 +7037,24 @@ 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); for (const prop of getPropertiesOfObjectType(source)) { - if (!isKnownProperty(target, prop.name)) { + if (!isKnownProperty(target, prop.name, isComparingJsxAttributes)) { 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 // reasoning about what went wrong. Debug.assert(!!errorNode); - errorNode = prop.valueDeclaration; - reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, - symbolToString(prop), typeToString(target)); + if (isJsxAttributes(errorNode)) { + // JsxAttributes has an object-literal flag and is underwent same type-assignablity check as normal object-literal. + // However, using an object-literal error message will be very confusing to the users so we give different a message. + reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target)); + } + else { + errorNode = prop.valueDeclaration; + reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, + symbolToString(prop), typeToString(target)); + } } return true; } @@ -10508,17 +10526,24 @@ namespace ts { } function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { + // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give JSXAttributes a contextual type + // which is a type of the parameter of the signature we are trying out. This is not the case if it is a statefull Jsx (i.e ReactComponenet class) + // So if that is the case, just return the type of the JsxAttribute in such contextual type with out going into resolving of the JsxOpeningLikeElement again + if ((attribute.parent).contextualType) { + return isJsxAttribute(attribute) ? getTypeOfPropertyOfType((attribute.parent).contextualType, attribute.name.text) : undefined; + } + const kind = attribute.kind; - const jsxElement = attribute.parent as JsxOpeningLikeElement; - const attrsType = getJsxElementAttributesType(jsxElement); + const jsxElement = attribute.parent.parent as JsxOpeningLikeElement; + const attrsType = getAttributesTypeFromJsxOpeningLikeElement(jsxElement); - if (attribute.kind === SyntaxKind.JsxAttribute) { + if (kind === SyntaxKind.JsxAttribute) { if (!attrsType || isTypeAny(attrsType)) { return undefined; } return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text); } - else if (attribute.kind === SyntaxKind.JsxSpreadAttribute) { + else if (kind === SyntaxKind.JsxSpreadAttribute) { return attrsType; } @@ -10595,6 +10620,9 @@ namespace ts { case SyntaxKind.JsxAttribute: case SyntaxKind.JsxSpreadAttribute: return getContextualTypeForJsxAttribute(parent); + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: + return getAttributesTypeFromJsxOpeningLikeElement(parent); } return undefined; } @@ -11081,66 +11109,145 @@ namespace ts { } } - function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Map) { - let correspondingPropType: Type = undefined; - - // Look up the corresponding property for this attribute - if (elementAttributesType === emptyObjectType && isUnhyphenatedJsxName(node.name.text)) { - // If there is no 'props' property, you may not have non-"data-" attributes - error(node.parent, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName()); - } - else if (elementAttributesType && !isTypeAny(elementAttributesType)) { - const correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text); - correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol); - if (isUnhyphenatedJsxName(node.name.text)) { - const attributeType = getTypeOfPropertyOfType(elementAttributesType, getTextOfPropertyName(node.name)) || getIndexTypeOfType(elementAttributesType, IndexKind.String); - if (attributeType) { - correspondingPropType = attributeType; + /** + * Get attributes symbol of the given Jsx opening-like element. The result is from resolving "attributes" property of the opening-like element. + * @param openingLikeElement a Jsx opening-like element + * @return a symbol table resulted from resolving "attributes" property or undefined if any of the attribute resolved to any or there is no attributes. + */ + function getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined { + const attributes = openingLikeElement.attributes; + let attributesTable = createMap(); + let spread: Type = emptyObjectType + let attributesArray: Symbol[] = []; + for (const attributeDecl of attributes.properties) { + const member = attributeDecl.symbol; + if (isJsxAttribute(attributeDecl)) { + let exprType: Type; + if (attributeDecl.initializer) { + exprType = checkExpression(attributeDecl.initializer); } else { - // If there's no corresponding property with this name, error - if (!correspondingPropType) { - error(node.name, Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType)); - return unknownType; - } + // is sugar for + exprType = trueType; } + + const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); + attributeSymbol.declarations = member.declarations; + attributeSymbol.parent = member.parent; + if (member.valueDeclaration) { + attributeSymbol.valueDeclaration = member.valueDeclaration; + } + attributeSymbol.type = exprType; + attributeSymbol.target = member; + attributesTable[attributeSymbol.name] = attributeSymbol; + attributesArray.push(attributeSymbol); + } + else { + Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); + if (attributesArray.length > 0) { + spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), /*isFromObjectLiteral*/ true); + attributesArray = []; + attributesTable = createMap(); + } + const exprType = checkExpression(attributeDecl.expression); + const widenExprType = getWidenedType(exprType); + if (!(widenExprType.flags & (TypeFlags.Object | TypeFlags.Any))) { + error(attributeDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); + return undefined; + } + if (isTypeAny(widenExprType)) { + return undefined; + } + spread = getSpreadType(spread, exprType, /*isFromObjectLiteral*/ false); } } - let exprType: Type; - if (node.initializer) { - exprType = checkExpression(node.initializer); - } - else { - // is sugar for - exprType = booleanType; + if (spread !== emptyObjectType) { + if (attributesArray.length > 0) { + spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), /*isFromObjectLiteral*/ true); + attributesArray = []; + attributesTable = createMap(); + } + attributesArray = getPropertiesOfType(spread); } - if (correspondingPropType) { - checkTypeAssignableTo(exprType, correspondingPropType, node); - } + return attributesArray; + } - nameTable[node.name.text] = true; - return exprType; + /** + * Create anonymous type from given attributes symbol table. + * @param jsxAttributesSymb a JsxAttributes node containing attributes in attributesTable + * @param attributesTable a symbol table of attributes property + */ + function createJsxAttributesType(jsxAttributesSymb: Symbol, attributesTable: Map) { + const result = createAnonymousType(jsxAttributesSymb, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral; + result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag; + result.objectFlags |= ObjectFlags.ObjectLiteral; + return result; } - function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map) { - const type = checkExpression(node.expression); - const props = getPropertiesOfType(type); - for (const prop of props) { - // Is there a corresponding property in the element attributes type? Skip checking of properties - // that have already been assigned to, as these are not actually pushed into the resulting type - if (!nameTable[prop.name]) { - const targetPropSym = getPropertyOfType(elementAttributesType, prop.name); - if (targetPropSym) { - const msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name); - checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(targetPropSym), node, undefined, msg); + /** + * Check JSXAttributes. This function is used when we are trying to figure out call signature for JSX opening-like element. + * In "checkApplicableSignatureForJsxOpeningLikeElement", we get type of arguments by checking the JSX opening-like element attributes property with contextual type. + * @param node a JSXAttributes to be resolved of its typea + */ + function checkJsxAttributes(node: JsxAttributes) { + const symbolArray = getJsxAttributesSymbolArrayFromAttributesProperty(node.parent as JsxOpeningLikeElement); + let argAttributesType = anyType as Type; + if (symbolArray) { + const symbolTable = createMap(); + forEach(symbolArray, (attr) => { + symbolTable[attr.name] = attr; + }); + argAttributesType = createJsxAttributesType(node.symbol, symbolTable); + } + return argAttributesType; + } + + /** + * Check whether the given attributes of JsxOpeningLikeElement is assignable to its corresponding tag-name attributes type. + * Resolve the type of attributes of the openingLikeElement through checking type of tag-name + * Check assignablity between given attributes property, "attributes" and the target attributes resulted from resolving tag-name + * @param openingLikeElement an opening-like JSX element to check its JSXAttributes + */ + function checkJSXAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) { + let targetAttributesType: Type; + // targetAttributesType is a type of an attributes from resolving tagnmae of an opening-like JSX element. + if (isJsxIntrinsicIdentifier(openingLikeElement.tagName)) { + targetAttributesType = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement); + } + else { + targetAttributesType = getCustomJsxElementAttributesType(openingLikeElement); + } + + const symbolArray = getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement); + // sourceAttributesType is a type of an attributes properties. + // i.e
+ // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType. + let sourceAttributesType = anyType as Type; + let isSourceAttributesTypeEmpty = true; + if (symbolArray) { + // Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type + const symbolTable = createMap(); + forEach(symbolArray, (attr) => { + if (isUnhyphenatedJsxName(attr.name) || getPropertyOfType(targetAttributesType, attr.name)) { + symbolTable[attr.name] = attr; + isSourceAttributesTypeEmpty = false; } + }); - nameTable[prop.name] = true; - } + sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes.symbol, symbolTable); + } + + // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type. + // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass. + if (targetAttributesType === emptyObjectType && !isTypeAny(sourceAttributesType) && !isSourceAttributesTypeEmpty) { + error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName()); + } + else { + checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement); } - return type; } function getJsxType(name: string) { @@ -11254,29 +11361,129 @@ namespace ts { } /** - * Given React element instance type and the class type, resolve the Jsx type - * Pass elemType to handle individual type in the union typed element type. + * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component. + * Return only attributes type of successfully resolved call signature. + * This function assumes that the caller handled other possible element type of the JSX element. + * Unlike tryGetAllJsxStatelessFunctionAttributesType, this function is a default behavior of type-checkers. + * @param openingLikeElement a JSX opening-like element to find attributes type + * @param elementType a type of the opening-like element. This elementType can't be an union type + * @param elemInstanceType an element instance type (the result of newing or invoking this tag) + * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global + */ + function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type { + Debug.assert(!(elementType.flags & TypeFlags.Union)); + if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { + // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type + if (jsxElementType) { + // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. + const callSignature = getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); + const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); + let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); + if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { + // Intersect in JSX.IntrinsicAttributes if it exists + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); + if (intrinsicAttributes !== unknownType) { + paramType = intersectTypes(intrinsicAttributes, paramType); + } + return paramType; + } + } + } + return undefined; + } + + /** + * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component. + * Return all attributes type of resolved call signature including candidate signatures. + * This function assumes that the caller handled other possible element type of the JSX element. + * This function is a behavior used by language service when looking up completion in JSX element., + * @param openingLikeElement a JSX opening-like element to find attributes type + * @param elementType a type of the opening-like element. This elementType can't be an union type + * @param elemInstanceType an element instance type (the result of newing or invoking this tag) + * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global */ - function getResolvedJsxType(node: JsxOpeningLikeElement, elemType?: Type, elemClassType?: Type): Type { - if (!elemType) { - elemType = checkExpression(node.tagName); - } - if (elemType.flags & TypeFlags.Union) { - const types = (elemType).types; - return getUnionType(map(types, type => { - return getResolvedJsxType(node, type, elemClassType); + function tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type { + Debug.assert(!(elementType.flags & TypeFlags.Union)); + if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { + // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type + if (jsxElementType) { + // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. + const candidatesOutArray: Signature[] = []; + getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray); + let result: Type; + let defaultResult: Type; + for (const candidate of candidatesOutArray) { + const callReturnType = getReturnTypeOfSignature(candidate); + const paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); + if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { + let shouldBeCandidate = true; + for (const attribute of openingLikeElement.attributes.properties) { + if (isJsxAttribute(attribute) && + isUnhyphenatedJsxName(attribute.name.text) && + !getPropertyOfType(paramType, attribute.name.text)) { + shouldBeCandidate = false; + break; + } + } + if (shouldBeCandidate) { + result = intersectTypes(result, paramType); + } + defaultResult = intersectTypes(defaultResult, paramType); + } + } + + // If we can't find any matching, just return everything. + if (!result) { + result = defaultResult; + } + // Intersect in JSX.IntrinsicAttributes if it exists + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); + if (intrinsicAttributes !== unknownType) { + result = intersectTypes(intrinsicAttributes, result); + } + return result; + } + } + return undefined; + } + + /** + * Resolve attributes type of the given node. The function is intended to initially be called from getAttributesTypeFromJsxOpeningLikeElement which already handle JSX-intrinsic-element. + * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement + * @param elementType an instance type of the given node + * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts) + * @return attributes'type if able to resolve the type of node + * anyType if there is no type ElementAttributesProperty or there is an error + * emptyObjectType if there is no "prop" in the element instance type + **/ + function resolveCustomJsxElementAttributesType(openingLikeElement: JsxOpeningLikeElement, + shouldIncludeAllStatelessAttributesType: boolean, + elementType?: Type, + elementClassType?: Type): Type { + if (!elementType) { + elementType = checkExpression(openingLikeElement.tagName); + } + + if (elementType.flags & TypeFlags.Union) { + const types = (elementType as UnionType).types; + return getUnionType(types.map(type => { + return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType); }), /*subtypeReduction*/ true); } // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type - if (elemType.flags & TypeFlags.String) { + // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type + if (elementType.flags & TypeFlags.String) { return anyType; } - else if (elemType.flags & TypeFlags.StringLiteral) { + else if (elementType.flags & TypeFlags.StringLiteral) { // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type + // For example: + // var CustomTag: "h1" = "h1"; + // Hello World const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); if (intrinsicElementsType !== unknownType) { - const stringLiteralTypeName = (elemType).text; + const stringLiteralTypeName = (elementType).text; const intrinsicProp = getPropertyOfType(intrinsicElementsType, stringLiteralTypeName); if (intrinsicProp) { return getTypeOfSymbol(intrinsicProp); @@ -11285,37 +11492,27 @@ namespace ts { if (indexSignatureType) { return indexSignatureType; } - error(node, Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements); + error(openingLikeElement, Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements); } // If we need to report an error, we already done so here. So just return any to prevent any more error downstream return anyType; } // Get the element instance type (the result of newing or invoking this tag) - const elemInstanceType = getJsxElementInstanceType(node, elemType); + const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType); - if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) { - // Is this is a stateless function component? See if its single signature's return type is - // assignable to the JSX Element Type - if (jsxElementType) { - const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call); - const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0]; - const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); - let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); - if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { - // Intersect in JSX.IntrinsicAttributes if it exists - const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); - if (intrinsicAttributes !== unknownType) { - paramType = intersectTypes(intrinsicAttributes, paramType); - } - return paramType; - } - } + // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type + const statelessAttributesType = shouldIncludeAllStatelessAttributesType ? + tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) : + defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType); + + if (statelessAttributesType) { + return statelessAttributesType; } // Issue an error if this return type isn't assignable to JSX.ElementClass - if (elemClassType) { - checkTypeRelatedTo(elemInstanceType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); + if (elementClassType) { + checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } if (isTypeAny(elemInstanceType)) { @@ -11344,7 +11541,7 @@ namespace ts { } else if (attributesType.flags & TypeFlags.Union) { // Props cannot be a union type - error(node.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType)); + error(openingLikeElement.tagName, Diagnostics.JSX_element_attributes_type_0_may_not_be_a_union_type, typeToString(attributesType)); return anyType; } else { @@ -11374,30 +11571,62 @@ namespace ts { } /** - * Given an opening/self-closing element, get the 'element attributes type', i.e. the type that tells - * us which attributes are valid on a given element. + * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name. + * The function is intended to be called from a function which has checked that the opening element is an intrinsic element. + * @param node an intrinsic JSX oopening-like element */ - function getJsxElementAttributesType(node: JsxOpeningLikeElement): Type { + function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { const links = getNodeLinks(node); - if (!links.resolvedJsxType) { - if (isJsxIntrinsicIdentifier(node.tagName)) { - const symbol = getIntrinsicTagSymbol(node); - if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) { - return links.resolvedJsxType = getTypeOfSymbol(symbol); - } - else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) { - return links.resolvedJsxType = getIndexInfoOfSymbol(symbol, IndexKind.String).type; - } - else { - return links.resolvedJsxType = unknownType; - } + if (!links.resolvedJsxElementAttributesType) { + const symbol = getIntrinsicTagSymbol(node); + if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) { + return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol); + } + else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) { + return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, IndexKind.String).type; } else { - const elemClassType = getJsxGlobalElementClassType(); - return links.resolvedJsxType = getResolvedJsxType(node, undefined, elemClassType); + return links.resolvedJsxElementAttributesType = unknownType; } } - return links.resolvedJsxType; + return links.resolvedJsxElementAttributesType; + } + + /** + * Get attributes type of the given custom opening-like Jsx element. + * The function is intended to be called from a function which has handle intrinsic Jsx element already. + * @param node a custom Jsx opening-like element + */ + function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType = false): Type { + const links = getNodeLinks(node); + if (!links.resolvedJsxElementAttributesType) { + const elemClassType = getJsxGlobalElementClassType(); + return links.resolvedJsxElementAttributesType = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, undefined, elemClassType); + } + return links.resolvedJsxElementAttributesType; + } + + function getAllAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { + if (isJsxIntrinsicIdentifier(node.tagName)) { + return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); + } + else { + return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true); + } + } + + /** + * Get the attributes type which is the type that indicate which attributes are valid on the given JSXOpeningLikeElement. + * @param node a JSXOpeningLikeElement node + * @return an attributes type of the given node + */ + function getAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { + if (isJsxIntrinsicIdentifier(node.tagName)) { + return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); + } + else { + return getCustomJsxElementAttributesType(node); + } } /** @@ -11406,7 +11635,7 @@ namespace ts { * that have no matching element attributes type property. */ function getJsxAttributePropertySymbol(attrib: JsxAttribute): Symbol { - const attributesType = getJsxElementAttributesType(attrib.parent); + const attributesType = getAttributesTypeFromJsxOpeningLikeElement(attrib.parent.parent as JsxOpeningElement); const prop = getPropertyOfType(attributesType, attrib.name.text); return prop || unknownSymbol; } @@ -11437,14 +11666,15 @@ namespace ts { } } - function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) { - checkGrammarJsxElement(node); - checkJsxPreconditions(node); + function checkJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement) { + checkGrammarJsxElement(openingLikeElement); + checkJsxPreconditions(openingLikeElement); + // The reactNamespace symbol should be marked as 'used' so we don't incorrectly elide its import. And if there // is no reactNamespace symbol in scope when targeting React emit, we should issue an error. const reactRefErr = compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; const reactNamespace = compilerOptions.reactNamespace ? compilerOptions.reactNamespace : "React"; - const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace); + const reactSym = resolveName(openingLikeElement.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace); if (reactSym) { // Mark local symbol as referenced here because it might not have been marked // if jsx emit was not react as there wont be error being emitted @@ -11456,38 +11686,7 @@ namespace ts { } } - const targetAttributesType = getJsxElementAttributesType(node); - - const nameTable = createMap(); - // Process this array in right-to-left order so we know which - // attributes (mostly from spreads) are being overwritten and - // thus should have their types ignored - let sawSpreadedAny = false; - for (let i = node.attributes.length - 1; i >= 0; i--) { - if (node.attributes[i].kind === SyntaxKind.JsxAttribute) { - checkJsxAttribute((node.attributes[i]), targetAttributesType, nameTable); - } - else { - Debug.assert(node.attributes[i].kind === SyntaxKind.JsxSpreadAttribute); - const spreadType = checkJsxSpreadAttribute((node.attributes[i]), targetAttributesType, nameTable); - if (isTypeAny(spreadType)) { - sawSpreadedAny = true; - } - } - } - - // Check that all required properties have been provided. If an 'any' - // was spreaded in, though, assume that it provided all required properties - if (targetAttributesType && !sawSpreadedAny) { - const targetProperties = getPropertiesOfType(targetAttributesType); - for (let i = 0; i < targetProperties.length; i++) { - if (!(targetProperties[i].flags & SymbolFlags.Optional) && - !nameTable[targetProperties[i].name]) { - - error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType)); - } - } - } + checkJSXAttributesAssignableToTagnameAttributes(openingLikeElement); } function checkJsxExpression(node: JsxExpression) { @@ -11936,6 +12135,13 @@ namespace ts { let isDecorator: boolean; let spreadArgIndex = -1; + if (isJsxOpeningLikeElement(node)) { + // For JSX opening-like element, we will ignore regular arity check (which is what is done here). + // Instead, the arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement" as we are required to figure out + // all property inside give attributes. + return true; + } + if (node.kind === SyntaxKind.TaggedTemplateExpression) { const tagExpression = node; @@ -11977,7 +12183,7 @@ namespace ts { argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; - // If we are missing the close paren, the call is incomplete. + // If we are missing the close parenthesis, the call is incomplete. callIsIncomplete = callExpression.arguments.end === callExpression.end; typeArguments = callExpression.typeArguments; @@ -12135,6 +12341,51 @@ namespace ts { return typeArgumentsAreAssignable; } + /** + * Check if the given signature can possibly be a signature called by the JSX opening-like element. + * @param node a JSX opening-like element we are trying to figure its call signature + * @param signature a candidate signature we are trying whether it is a call signature + * @param relation a relationship to check parameter and argument type + * @param excludeArgument + */ + function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map) { + const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; + // Stateless function components can have maximum of three arguments: "props", "context", and "updater". + // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, + // can be specified by users through attributes property. + const paramType = getTypeAtPosition(signature, 0); + + // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true: + // 1. callIsInCompletes + // 2. attributes property has same number of properties as the parameter object type. + // 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 argType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined); + const argProperties = getPropertiesOfType(argType); + const paramProperties = getPropertiesOfType(paramType); + if (callIsIncomplete) { + return true; + } + else if (argProperties.length === paramProperties.length && checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { + return true; + } + else { + let shouldCheckArgumentAndParameter = true; + for (const arg of argProperties) { + if (!getPropertyOfType(paramType, arg.name) && isUnhyphenatedJsxName(arg.name)) { + shouldCheckArgumentAndParameter = false; + break; + } + } + if (shouldCheckArgumentAndParameter && checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { + return true; + } + } + return false; + } + function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { const thisType = getThisTypeOfSignature(signature); if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { @@ -12217,8 +12468,13 @@ namespace ts { // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below. return undefined; } + else if (isJsxOpeningLikeElement(node)) { + // For a JSX opening-like element, even though we will recheck the attributes again in "checkApplicableSignatureForJsxOpeningLikeElement" to figure out correct arity. + // We still return it here because when using infer type-argument we still have to getEffectiveArgument in trying to infer type-argument. + args = node.attributes.properties.length > 0 ? [node.attributes] : []; + } else { - args = (node).arguments || emptyArray; + args = node.arguments || emptyArray; } return args; @@ -12499,10 +12755,11 @@ namespace ts { function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[], headMessage?: DiagnosticMessage): Signature { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; + const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); let typeArguments: TypeNode[]; - if (!isTaggedTemplate && !isDecorator) { + if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) { typeArguments = (node).typeArguments; // We already perform checking on the type arguments on the class declaration itself. @@ -12536,7 +12793,7 @@ namespace ts { // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. let excludeArgument: boolean[]; - if (!isDecorator) { + if (!isDecorator && !isJsxOpeningOrSelfClosingElement) { // We do not need to call `getEffectiveArgumentCount` here as it only // applies when calculating the number of arguments for a decorator. for (let i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { @@ -12604,6 +12861,14 @@ namespace ts { return result; } + // Do not report any error if we are doing so for stateless function component as such error will be error will be handle in "resolveCustomJsxElementAttributesType". + if (isJsxOpeningOrSelfClosingElement) { + // If this is a type resolution session, e.g. Language Service, just return undefined as the language service can decide how to proceed with this failure. + // (see getDefinitionAtPosition which simply get the symbol and return the first declaration of the JSXopeningLikeElement node) + // otherwise, just return the latest signature candidate we try so far so that when we report an error we will get better error message. + return produceDiagnostics ? candidateForArgumentError : undefined; + } + // No signatures were applicable. Now report errors based on the last applicable signature with // no arguments excluded from assignability checks. // If candidate is undefined, it means that no candidates had a suitable arity. In that case, @@ -12660,6 +12925,9 @@ namespace ts { return resolveErrorCall(node); function reportError(message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { + if (isJsxOpeningOrSelfClosingElement) { + return; + } let errorInfo: DiagnosticMessageChain; errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2); if (headMessage) { @@ -12699,7 +12967,10 @@ namespace ts { } candidate = getSignatureInstantiation(candidate, typeArgumentTypes); } - if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { + if (isJsxOpeningOrSelfClosingElement && !checkApplicableSignatureForJsxOpeningLikeElement(node, candidate, relation)) { + break; + } + else if (!isJsxOpeningOrSelfClosingElement && !checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { break; } const index = excludeArgument ? indexOf(excludeArgument, true) : -1; @@ -13011,6 +13282,69 @@ namespace ts { return resolveCall(node, callSignatures, candidatesOutArray, headMessage); } + /** + * + * @param openingLikeElement + * @param elementType + * @param candidatesOutArray + */ + function getResolvedJSXStatelessFunctionSignature(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { + Debug.assert(!(elementType.flags & TypeFlags.Union)); + const links = getNodeLinks(openingLikeElement); + // If getResolvedSignature has already been called, we will have cached the resolvedSignature. + // However, it is possible that either candidatesOutArray was not passed in the first time, + // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work + // to correctly fill the candidatesOutArray. + const cached = links.resolvedSignature; + if (cached && cached !== resolvingSignature && !candidatesOutArray) { + return cached; + } + links.resolvedSignature = resolvingSignature; + + let callSignature = resolvedStateLessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); + if (!callSignature || callSignature === unknownSignature) { + const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call); + callSignature = callSignatures[callSignatures.length - 1]; + } + links.resolvedSignature = callSignature; + // If signature resolution originated in control flow type analysis (for example to compute the + // assigned type in a flow assignment) we don't cache the result as it may be based on temporary + // types from the control flow analysis. + links.resolvedSignature = flowLoopStart === flowLoopCount ? callSignature : cached; + return callSignature; + } + + /** + * Try treating a given opening-like element as stateless function component and try to resolve a signature. + * @param openingLikeElement an JsxOpeningLikeElement we want to try resolve its state-less function if possible + * @param elementType a type of the opening-like JSX element, a result of resolving tagName in opening-like element. + * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service; + * the function will fill it up with appropriate candidate signatures + * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions. + * otherwise return undefined if tag-name of the opening-like element doesn't have call signatures + */ + function resolvedStateLessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { + if (elementType.flags & TypeFlags.Union) { + const types = (elementType as UnionType).types; + let result: Signature; + types.map(type => { + // This is mainly to fill in all the candidates if there is one. + result = result || resolvedStateLessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); + }); + + return result; + } + + const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call); + if (callSignatures && callSignatures.length > 0) { + let callSignature: Signature; + callSignature = resolveCall(openingLikeElement, callSignatures, candidatesOutArray); + return callSignature; + } + + return undefined; + } + function resolveSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature { switch (node.kind) { case SyntaxKind.CallExpression: @@ -13021,12 +13355,20 @@ namespace ts { return resolveTaggedTemplateExpression(node, candidatesOutArray); case SyntaxKind.Decorator: return resolveDecorator(node, candidatesOutArray); + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxSelfClosingElement: + return resolvedStateLessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray); } Debug.fail("Branch in 'resolveSignature' should be unreachable."); } - // candidatesOutArray is passed by signature help in the language service, and collectCandidates - // must fill it up with the appropriate candidate signatures + /** + * Resolve a signature of a given call-like expression. + * @param node a call-like expression to try resolve a signature for + * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service; + * the function will fill it up with appropriate candidate signatures + * @return a signature of the call-like expression or undefined if one can't be found + */ function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature { const links = getNodeLinks(node); // If getResolvedSignature has already been called, we will have cached the resolvedSignature. @@ -14582,6 +14924,8 @@ namespace ts { return checkJsxElement(node); case SyntaxKind.JsxSelfClosingElement: return checkJsxSelfClosingElement(node); + case SyntaxKind.JsxAttributes: + return checkJsxAttributes(node); case SyntaxKind.JsxOpeningElement: Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } @@ -20609,7 +20953,8 @@ namespace ts { function checkGrammarJsxElement(node: JsxOpeningLikeElement) { const seen = createMap(); - for (const attr of node.attributes) { + + for (const attr of node.attributes.properties) { if (attr.kind === SyntaxKind.JsxSpreadAttribute) { continue; } From e0a5d63e124060a7c815f61442cded986c3d800f Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 08:54:10 -0800 Subject: [PATCH 03/25] Update emitter to use JSXAttributes node instead of JSXAttribute node array --- src/compiler/emitter.ts | 18 +++++++++++++++--- src/compiler/factory.ts | 26 ++++++++++++++++++++------ src/compiler/transformers/jsx.ts | 2 +- src/compiler/visitor.ts | 14 +++++++++++--- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ce37492f66662..0f0abfc94ce2e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -712,6 +712,8 @@ const _super = (function (geti, seti) { return emitJsxClosingElement(node); case SyntaxKind.JsxAttribute: return emitJsxAttribute(node); + case SyntaxKind.JsxAttributes: + return emitJsxAttributes(node); case SyntaxKind.JsxSpreadAttribute: return emitJsxSpreadAttribute(node); case SyntaxKind.JsxExpression: @@ -1969,15 +1971,21 @@ const _super = (function (geti, seti) { write("<"); emitJsxTagName(node.tagName); write(" "); - emitList(node, node.attributes, ListFormat.JsxElementAttributes); + // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap + if (node.attributes.properties && node.attributes.properties.length > 0) { + emit(node.attributes); + } write("/>"); } function emitJsxOpeningElement(node: JsxOpeningElement) { write("<"); emitJsxTagName(node.tagName); - writeIfAny(node.attributes, " "); - emitList(node, node.attributes, ListFormat.JsxElementAttributes); + writeIfAny(node.attributes.properties, " "); + // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap + if (node.attributes.properties && node.attributes.properties.length > 0) { + emit(node.attributes); + } write(">"); } @@ -1991,6 +1999,10 @@ const _super = (function (geti, seti) { write(">"); } + function emitJsxAttributes(node: JsxAttributes) { + emitList(node, node.properties, ListFormat.JsxElementAttributes); + } + function emitJsxAttribute(node: JsxAttribute) { emit(node.name); emitWithPrefix("=", node.initializer); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index fd2b7c1ccee34..6f8ecaa03ff65 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1237,28 +1237,28 @@ namespace ts { return node; } - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) { const node = createNode(SyntaxKind.JsxSelfClosingElement, location); node.tagName = tagName; - node.attributes = createNodeArray(attributes); + node.attributes = attributes; return node; } - export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) { if (node.tagName !== tagName || node.attributes !== attributes) { return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node); } return node; } - export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) { const node = createNode(SyntaxKind.JsxOpeningElement, location); node.tagName = tagName; - node.attributes = createNodeArray(attributes); + node.attributes = attributes; return node; } - export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) { if (node.tagName !== tagName || node.attributes !== attributes) { return updateNode(createJsxOpeningElement(tagName, attributes, node), node); } @@ -1278,6 +1278,20 @@ namespace ts { return node; } + export function createJsxAttributes(properties: JsxAttributeLike[], location?: TextRange) { + const jsxAttributes = createNode(SyntaxKind.JsxAttributes, location); + setEmitFlags(jsxAttributes, EmitFlags.NoSourceMap); + jsxAttributes.properties = createNodeArray(properties); + return jsxAttributes; + } + + export function updateJsxAttributes(jsxAttributes: JsxAttributes, properties: JsxAttributeLike[]) { + if (jsxAttributes.properties !== properties) { + return updateNode(createJsxAttributes(properties, jsxAttributes), jsxAttributes); + } + return jsxAttributes; + } + export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) { const node = createNode(SyntaxKind.JsxAttribute, location); node.name = name; diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 95a4016bb0aeb..9dbe83a6d3bc5 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -86,7 +86,7 @@ namespace ts { function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) { const tagName = getTagName(node); let objectProperties: Expression; - const attrs = node.attributes; + const attrs = node.attributes.properties; if (attrs.length === 0) { // When there are no attributes, React wants "null" objectProperties = createNull(); diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c1dd284028eb8..c718c461b3f58 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -461,13 +461,17 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: result = reduceNode((node).tagName, f, result); - result = reduceLeft((node).attributes, f, result); + result = reduceNode((node).attributes, f, result); break; case SyntaxKind.JsxClosingElement: result = reduceNode((node).tagName, f, result); break; + case SyntaxKind.JsxAttributes: + result = reduceLeft((node).properties, f, result); + break; + case SyntaxKind.JsxAttribute: result = reduceNode((node).name, f, result); result = reduceNode((node).initializer, f, result); @@ -1074,15 +1078,19 @@ namespace ts { visitNodes((node).children, visitor, isJsxChild), visitNode((node).closingElement, visitor, isJsxClosingElement)); + case SyntaxKind.JsxAttributes: + return updateJsxAttributes(node, + visitNodes((node).properties, visitor, isJsxAttributeLike)); + case SyntaxKind.JsxSelfClosingElement: return updateJsxSelfClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - visitNodes((node).attributes, visitor, isJsxAttributeLike)); + visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxOpeningElement: return updateJsxOpeningElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - visitNodes((node).attributes, visitor, isJsxAttributeLike)); + visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxClosingElement: return updateJsxClosingElement(node, From e5c9409d145a7a1c649f4181e6d3b791f8963034 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 08:56:08 -0800 Subject: [PATCH 04/25] Add language service support for JSXAttributes Add language service support for JSXAttributes Add completion support Add find-all-references support Add goto-definition support --- src/services/completions.ts | 33 ++++++++++---- src/services/findAllReferences.ts | 71 ++----------------------------- src/services/goToDefinition.ts | 40 ++++++++++++++++- src/services/services.ts | 70 ++++++++++++++++++++++++++++++ src/services/signatureHelp.ts | 32 ++++++++++---- src/services/symbolDisplay.ts | 27 +++++++++--- src/services/types.ts | 5 +++ src/services/utilities.ts | 1 + 8 files changed, 188 insertions(+), 91 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index b710aa8cd78bb..da0e0b87e0334 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1030,10 +1030,10 @@ namespace ts.Completions { let attrsType: Type; if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) { // Cursor is inside a JSX self-closing element or opening element - attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); + attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes.properties); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -1375,13 +1375,18 @@ namespace ts.Completions { case SyntaxKind.LessThanSlashToken: case SyntaxKind.SlashToken: case SyntaxKind.Identifier: + case SyntaxKind.JsxAttributes: case SyntaxKind.JsxAttribute: case SyntaxKind.JsxSpreadAttribute: if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) { return parent; } else if (parent.kind === SyntaxKind.JsxAttribute) { - return parent.parent; + // Currently we parse JsxOpeninLikeElement as: + // JsxOpeninLikeElement + // attributes: JsxAttributes + // properties: NodeArray + return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; } break; @@ -1390,7 +1395,11 @@ namespace ts.Completions { // whose parent is a JsxOpeningLikeElement case SyntaxKind.StringLiteral: if (parent && ((parent.kind === SyntaxKind.JsxAttribute) || (parent.kind === SyntaxKind.JsxSpreadAttribute))) { - return parent.parent; + // Currently we parse JsxOpeninLikeElement as: + // JsxOpeninLikeElement + // attributes: JsxAttributes + // properties: NodeArray + return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; } break; @@ -1398,13 +1407,21 @@ namespace ts.Completions { case SyntaxKind.CloseBraceToken: if (parent && parent.kind === SyntaxKind.JsxExpression && - parent.parent && - (parent.parent.kind === SyntaxKind.JsxAttribute)) { - return parent.parent.parent; + parent.parent && parent.parent.kind === SyntaxKind.JsxAttribute) { + // Currently we parse JsxOpeninLikeElement as: + // JsxOpeninLikeElement + // attributes: JsxAttributes + // properties: NodeArray + // each JsxAttribute can have initializer as JsxExpression + return /*JsxExpression*/parent./*JsxAttribute*/parent./*JsxAttributes*/parent.parent as JsxOpeningLikeElement; } if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) { - return parent.parent; + // Currently we parse JsxOpeninLikeElement as: + // JsxOpeninLikeElement + // attributes: JsxAttributes + // properties: NodeArray + return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; } break; diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 9765780ee7c8f..549be662b81c5 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1000,7 +1000,7 @@ namespace ts.FindAllReferences { // to get a contextual type for it, and add the property symbol from the contextual // type to the search set if (containingObjectLiteralElement) { - forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), contextualSymbol => { + forEach(getPropertySymbolsFromContextualType(typeChecker, containingObjectLiteralElement), contextualSymbol => { addRange(result, typeChecker.getRootSymbols(contextualSymbol)); }); @@ -1130,7 +1130,7 @@ namespace ts.FindAllReferences { // compare to our searchSymbol const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); if (containingObjectLiteralElement) { - const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement), contextualSymbol => { + const contextualSymbol = forEach(getPropertySymbolsFromContextualType(typeChecker, containingObjectLiteralElement), contextualSymbol => { return forEach(typeChecker.getRootSymbols(contextualSymbol), s => searchSymbols.indexOf(s) >= 0 ? s : undefined); }); @@ -1138,7 +1138,7 @@ namespace ts.FindAllReferences { return contextualSymbol; } - // If the reference location is the name of property from object literal destructuring pattern + // If the reference location is the name of property from object literal destructing pattern // Get the property symbol from the object literal's type and look if thats the search symbol // In below eg. get 'property' from type of elems iterating type // for ( { property: p2 } of elems) { } @@ -1184,42 +1184,6 @@ namespace ts.FindAllReferences { }); } - function getNameFromObjectLiteralElement(node: ObjectLiteralElement) { - if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; - // treat computed property names where expression is string/numeric literal as just string/numeric literal - if (isStringOrNumericLiteral(nameExpression.kind)) { - return (nameExpression).text; - } - return undefined; - } - return (node.name).text; - } - - function getPropertySymbolsFromContextualType(node: ObjectLiteralElement): Symbol[] { - const objectLiteral = node.parent; - const contextualType = typeChecker.getContextualType(objectLiteral); - const name = getNameFromObjectLiteralElement(node); - if (name && contextualType) { - const result: Symbol[] = []; - const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - - if (contextualType.flags & TypeFlags.Union) { - forEach((contextualType).types, t => { - const symbol = t.getProperty(name); - if (symbol) { - result.push(symbol); - } - }); - } - return result; - } - return undefined; - } - /** Given an initial searchMeaning, extracted from a location, widen the search scope based on the declarations * of the corresponding symbol. e.g. if we are searching for "Foo" in value position, but "Foo" references a class * then we need to widen the search to include type positions as well. @@ -1361,35 +1325,6 @@ namespace ts.FindAllReferences { }); } - /** - * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } - */ - function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement { - switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - if (node.parent.kind === SyntaxKind.ComputedPropertyName) { - return isObjectLiteralPropertyDeclaration(node.parent.parent) ? node.parent.parent : undefined; - } - // intential fall through - case SyntaxKind.Identifier: - return isObjectLiteralPropertyDeclaration(node.parent) && node.parent.name === node ? node.parent : undefined; - } - return undefined; - } - - function isObjectLiteralPropertyDeclaration(node: Node): node is ObjectLiteralElement { - switch (node.kind) { - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return true; - } - return false; - } - /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */ function tryGetClassByExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined { return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent); diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 4c005640d6ae8..047987cf49b1a 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -87,6 +87,39 @@ namespace ts.GoToDefinition { declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); } + if (isJsxOpeningLikeElement(node.parent)) { + // For JSX opening-like element, the tag can be resolved either as stateful component (e.g class) or stateless function component. + // Because if it is a stateless function component with an error while trying to resolve the signature, we don't want to return all + // possible overloads but just the first one. + // For example: + // /*firstSource*/declare function MainButton(buttonProps: ButtonProps): JSX.Element; + // /*secondSource*/declare function MainButton(linkProps: LinkProps): JSX.Element; + // /*thirdSource*/declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; + // let opt =
; // We get undefined for resolved signature indicating an error, then just return the first declaration + const {symbolName, symbolKind, containerName} = getSymbolInfo(typeChecker, symbol, node); + return [createDefinitionInfo(symbol.valueDeclaration, symbolKind, symbolName, containerName)]; + } + + // If the current location we want to find its definition is in an object literal, try to get the contextual type for the + // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. + // For example + // interface Props{ + // /first*/prop1: number + // prop2: boolean + // } + // function Foo(arg: Props) {} + // Foo( { pr/*1*/op1: 10, prop2: true }) + const container = getContainingObjectLiteralElement(node); + if (container) { + const contextualType = typeChecker.getContextualType(node.parent.parent as Expression); + if (contextualType) { + let result: DefinitionInfo[] = []; + forEach(getPropertySymbolsFromContextualType(typeChecker, container), contextualSymbol => { + result = result.concat(getDefinitionFromSymbol(typeChecker, contextualSymbol, node)); + }); + return result; + } + } return getDefinitionFromSymbol(typeChecker, symbol, node); } @@ -251,6 +284,11 @@ namespace ts.GoToDefinition { function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined { const callLike = getAncestorCallLikeExpression(node); - return callLike && typeChecker.getResolvedSignature(callLike).declaration; + if (callLike) { + const resolvedSignature = typeChecker.getResolvedSignature(callLike); + // We have to check that resolvedSignature is not undefined because in the case of JSX opening-like element, + // it may not be a stateless function component which then will cause getResolvedSignature to return undefined. + return resolvedSignature && resolvedSignature.declaration; + } } } diff --git a/src/services/services.ts b/src/services/services.ts index 8abcf8f76846c..5ddae70d05a07 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1967,6 +1967,76 @@ namespace ts { } } + function isObjectLiteralPropertyDeclaration(node: Node): node is ObjectLiteralElement { + switch (node.kind) { + case SyntaxKind.JsxAttribute: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return true; + } + return false; + } + + function getNameFromObjectLiteralElement(node: ObjectLiteralElement) { + if (node.name.kind === SyntaxKind.ComputedPropertyName) { + const nameExpression = (node.name).expression; + // treat computed property names where expression is string/numeric literal as just string/numeric literal + if (isStringOrNumericLiteral(nameExpression.kind)) { + return (nameExpression).text; + } + return undefined; + } + return (node.name).text; + } + + /** + * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } + */ + /* @internal */ + export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement { + switch (node.kind) { + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + if (node.parent.kind === SyntaxKind.ComputedPropertyName) { + return isObjectLiteralPropertyDeclaration(node.parent.parent) ? node.parent.parent : undefined; + } + // intentionally fall through + case SyntaxKind.Identifier: + return isObjectLiteralPropertyDeclaration(node.parent) && + (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) && + (node.parent).name === node ? node.parent as ObjectLiteralElement : undefined; + } + return undefined; + } + + /* @internal */ + export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] { + const objectLiteral = node.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = getNameFromObjectLiteralElement(node); + if (name && contextualType) { + const result: Symbol[] = []; + const symbol = contextualType.getProperty(name); + if (symbol) { + result.push(symbol); + } + + if (contextualType.flags & TypeFlags.Union) { + forEach((contextualType).types, t => { + const symbol = t.getProperty(name); + if (symbol) { + result.push(symbol); + } + }); + } + return result; + } + return undefined; + } + function isArgumentOfElementAccessExpression(node: Node) { return node && node.parent && diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 211e55b23ba5e..43e1bfc595b73 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -168,7 +168,8 @@ namespace ts.SignatureHelp { export const enum ArgumentListKind { TypeArguments, CallArguments, - TaggedTemplateArguments + TaggedTemplateArguments, + JSXAttributesArguments } export interface ArgumentListInfo { @@ -264,18 +265,18 @@ namespace ts.SignatureHelp { if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) { const callExpression = node.parent; // There are 3 cases to handle: - // 1. The token introduces a list, and should begin a sig help session + // 1. The token introduces a list, and should begin a signature help session // 2. The token is either not associated with a list, or ends a list, so the session should end - // 3. The token is buried inside a list, and should give sig help + // 3. The token is buried inside a list, and should give signature help // // The following are examples of each: // // Case 1: - // foo<#T, U>(#a, b) -> The token introduces a list, and should begin a sig help session + // foo<#T, U>(#a, b) -> The token introduces a list, and should begin a signature help session // Case 2: // fo#o#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end // Case 3: - // foo(a#, #b#) -> The token is buried inside a list, and should give sig help + // foo(a#, #b#) -> The token is buried inside a list, and should give signature help // Find out if 'node' is an argument, a type argument, or neither if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) { @@ -295,7 +296,7 @@ namespace ts.SignatureHelp { // findListItemInfo can return undefined if we are not in parent's argument list // or type argument list. This includes cases where the cursor is: - // - To the right of the closing paren, non-substitution template, or template tail. + // - To the right of the closing parenthesize, non-substitution template, or template tail. // - Between the type arguments and the arguments (greater than token) // - On the target of the call (parent.func) // - On the 'new' keyword in a 'new' expression @@ -352,6 +353,22 @@ namespace ts.SignatureHelp { return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile); } + else if (node.parent && isJsxOpeningLikeElement(node.parent)) { + // Provide a signature help for JSX opening element or JSX self-closing element. + // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems") + // i.e + // export function MainButton(props: ButtonProps, context: any): JSX.Element { ... } + // ' '' - // That will give us 2 non-commas. We then add one for the last comma, givin us an + // That will give us 2 non-commas. We then add one for the last comma, giving us an // arg count of 3. const listChildren = argumentsList.getChildren(); @@ -435,7 +452,6 @@ namespace ts.SignatureHelp { : (tagExpression.template).templateSpans.length + 1; Debug.assert(argumentIndex === 0 || argumentIndex < argumentCount, `argumentCount < argumentIndex, ${argumentCount} < ${argumentIndex}`); - return { kind: ArgumentListKind.TaggedTemplateArguments, invocation: tagExpression, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 516b5d7fbc5b1..97e3b98b908fa 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -71,6 +71,9 @@ namespace ts.SymbolDisplay { } return unionPropertyKind; } + if (location.parent && isJsxAttribute(location.parent)) { + return ScriptElementKind.jsxAttribute; + } return ScriptElementKind.memberVariableElement; } @@ -114,23 +117,33 @@ namespace ts.SymbolDisplay { } // try get the call/construct signature from the type if it matches - let callExpression: CallExpression | NewExpression; + let callExpressionLike: CallExpression | NewExpression | JsxOpeningLikeElement; if (location.kind === SyntaxKind.CallExpression || location.kind === SyntaxKind.NewExpression) { - callExpression = location; + callExpressionLike = location; } else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) { - callExpression = location.parent; + callExpressionLike = location.parent; + } + else if (location.parent && isJsxOpeningLikeElement(location.parent) && isFunctionLike(symbol.valueDeclaration)) { + callExpressionLike = location.parent; } - if (callExpression) { + if (callExpressionLike) { const candidateSignatures: Signature[] = []; - signature = typeChecker.getResolvedSignature(callExpression, candidateSignatures); + signature = typeChecker.getResolvedSignature(callExpressionLike, candidateSignatures); if (!signature && candidateSignatures.length) { // Use the first candidate: signature = candidateSignatures[0]; } - const useConstructSignatures = callExpression.kind === SyntaxKind.NewExpression || callExpression.expression.kind === SyntaxKind.SuperKeyword; + let useConstructSignatures = false; + if (callExpressionLike.kind === SyntaxKind.NewExpression) { + useConstructSignatures = true; + } + else if (isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === SyntaxKind.SuperKeyword) { + useConstructSignatures = true; + } + const allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!contains(allSignatures, signature.target) && !contains(allSignatures, signature)) { @@ -160,6 +173,7 @@ namespace ts.SymbolDisplay { } switch (symbolKind) { + case ScriptElementKind.jsxAttribute: case ScriptElementKind.memberVariableElement: case ScriptElementKind.variableElement: case ScriptElementKind.constElement: @@ -373,6 +387,7 @@ namespace ts.SymbolDisplay { // For properties, variables and local vars: show the type if (symbolKind === ScriptElementKind.memberVariableElement || + symbolKind === ScriptElementKind.jsxAttribute || symbolFlags & SymbolFlags.Variable || symbolKind === ScriptElementKind.localVariableElement || isThisExpression) { diff --git a/src/services/types.ts b/src/services/types.ts index 4e04df3fc7caf..b21c974309131 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -758,6 +758,11 @@ namespace ts { export const directory = "directory"; export const externalModuleName = "external module name"; + + /** + * + **/ + export const jsxAttribute = "JSX attribute"; } export namespace ScriptElementKindModifier { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index cfb6aae010b63..8c7483889efbd 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -31,6 +31,7 @@ namespace ts { case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: case SyntaxKind.CatchClause: + case SyntaxKind.JsxAttribute: return SemanticMeaning.Value; case SyntaxKind.TypeParameter: From fdc6d7427478de29d51f71e6ab475360ad9c7ad5 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:19:04 -0800 Subject: [PATCH 05/25] Update existed conformance tests --- .../cases/conformance/jsx/tsxAttributeResolution3.tsx | 2 +- .../cases/conformance/jsx/tsxElementResolution12.tsx | 2 +- tests/cases/conformance/jsx/tsxEmit2.tsx | 2 +- tests/cases/conformance/jsx/tsxReactEmit2.tsx | 2 +- tests/cases/conformance/jsx/tsxReactEmit4.tsx | 2 +- tests/cases/conformance/jsx/tsxReactEmit5.tsx | 2 +- tests/cases/conformance/jsx/tsxReactEmit6.tsx | 2 +- .../jsx/tsxStatelessFunctionComponents1.tsx | 11 +++++++++++ 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx index dc0c2fed8d638..9a9e0d8245d28 100644 --- a/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx +++ b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx @@ -36,6 +36,6 @@ var obj5 = { x: 32, y: 32 }; var obj6 = { x: 'ok', y: 32, extra: 100 }; -// Error +// OK (spread override) var obj7 = { x: 'foo' }; diff --git a/tests/cases/conformance/jsx/tsxElementResolution12.tsx b/tests/cases/conformance/jsx/tsxElementResolution12.tsx index a5d8f2d812b4b..a4b47336ef891 100644 --- a/tests/cases/conformance/jsx/tsxElementResolution12.tsx +++ b/tests/cases/conformance/jsx/tsxElementResolution12.tsx @@ -15,7 +15,7 @@ var Obj1: Obj1type; interface Obj2type { new(n: string): { q?: number; pr: any }; } -var obj2: Obj2type; +var Obj2: Obj2type; ; // OK interface Obj3type { diff --git a/tests/cases/conformance/jsx/tsxEmit2.tsx b/tests/cases/conformance/jsx/tsxEmit2.tsx index 24f51a4583d86..8d90fccdcd109 100644 --- a/tests/cases/conformance/jsx/tsxEmit2.tsx +++ b/tests/cases/conformance/jsx/tsxEmit2.tsx @@ -7,7 +7,7 @@ declare module JSX { } } -var p1, p2, p3; +var p1: any, p2: any, p3: any; var spreads1 =
{p2}
; var spreads2 =
{p2}
; var spreads3 =
{p2}
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit2.tsx b/tests/cases/conformance/jsx/tsxReactEmit2.tsx index 96ab8c6046b27..762b36b843238 100644 --- a/tests/cases/conformance/jsx/tsxReactEmit2.tsx +++ b/tests/cases/conformance/jsx/tsxReactEmit2.tsx @@ -8,7 +8,7 @@ declare module JSX { } declare var React: any; -var p1, p2, p3; +var p1: any, p2: any, p3: any; var spreads1 =
{p2}
; var spreads2 =
{p2}
; var spreads3 =
{p2}
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit4.tsx b/tests/cases/conformance/jsx/tsxReactEmit4.tsx index a032a5a3985d1..3fbff0975a5e7 100644 --- a/tests/cases/conformance/jsx/tsxReactEmit4.tsx +++ b/tests/cases/conformance/jsx/tsxReactEmit4.tsx @@ -8,7 +8,7 @@ declare module JSX { } declare var React: any; -var p; +var p: any; var openClosed1 =
{blah} diff --git a/tests/cases/conformance/jsx/tsxReactEmit5.tsx b/tests/cases/conformance/jsx/tsxReactEmit5.tsx index c961a23ecfc77..f8787eb4aa35d 100644 --- a/tests/cases/conformance/jsx/tsxReactEmit5.tsx +++ b/tests/cases/conformance/jsx/tsxReactEmit5.tsx @@ -16,5 +16,5 @@ export var React; import {React} from "./test"; // Should emit test_1.React.createElement // and React.__spread -var foo; +var foo: any; var spread1 =
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit6.tsx b/tests/cases/conformance/jsx/tsxReactEmit6.tsx index 0e8c772a3f1bc..abc41a690d4b8 100644 --- a/tests/cases/conformance/jsx/tsxReactEmit6.tsx +++ b/tests/cases/conformance/jsx/tsxReactEmit6.tsx @@ -17,7 +17,7 @@ namespace M { namespace M { // Should emit M.React.createElement // and M.React.__spread - var foo; + var foo: any; var spread1 =
; // Quotes diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx index 5d64d22c757b5..6d7ffa21e0b91 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx @@ -9,17 +9,28 @@ function Greet(x: {name: string}) { function Meet({name = 'world'}) { return
Hello, {name}
; } +function MeetAndGreet(k: {"prop-name": string}) { + return
Hi Hi
; +} // OK let a = ; +let a1 = ; // Error let b = ; // OK let c = ; +let c1 = ; // OK let d = ; // Error let e = ; // Error let f = ; + +// OK +let g = ; +// Error +let h = ; + From b71f142e69db9e25d414926b2e54967a3d961dad Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:32:26 -0800 Subject: [PATCH 06/25] Add tests for using spread attributes resolution in JSX stateful component --- .../jsx/tsxSpreadAttributesResolution1.tsx | 18 ++++++++++ .../jsx/tsxSpreadAttributesResolution10.tsx | 27 ++++++++++++++ .../jsx/tsxSpreadAttributesResolution11.tsx | 36 +++++++++++++++++++ .../jsx/tsxSpreadAttributesResolution12.tsx | 34 ++++++++++++++++++ .../jsx/tsxSpreadAttributesResolution2.tsx | 24 +++++++++++++ .../jsx/tsxSpreadAttributesResolution3.tsx | 26 ++++++++++++++ .../jsx/tsxSpreadAttributesResolution4.tsx | 25 +++++++++++++ .../jsx/tsxSpreadAttributesResolution5.tsx | 25 +++++++++++++ .../jsx/tsxSpreadAttributesResolution6.tsx | 22 ++++++++++++ .../jsx/tsxSpreadAttributesResolution7.tsx | 29 +++++++++++++++ .../jsx/tsxSpreadAttributesResolution8.tsx | 31 ++++++++++++++++ .../jsx/tsxSpreadAttributesResolution9.tsx | 29 +++++++++++++++ 12 files changed, 326 insertions(+) create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution1.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution10.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution11.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution3.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution4.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution6.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution7.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution8.tsx create mode 100644 tests/cases/conformance/jsx/tsxSpreadAttributesResolution9.tsx diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution1.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution1.tsx new file mode 100644 index 0000000000000..6d5225df2d902 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution1.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +class Poisoned extends React.Component<{}, {}> { + render() { + return
Hello
; + } +} + +const obj: Object = {}; + +// OK +let p = ; +let y = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution10.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution10.tsx new file mode 100644 index 0000000000000..6410f075ae962 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution10.tsx @@ -0,0 +1,27 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface OptionProp { + x?: 2 +} + +class Opt extends React.Component { + render() { + return
Hello
; + } +} + +const obj: OptionProp = {}; +const obj1: OptionProp = { + x: 2 +} + +// Error +let y = ; +let y1 = ; +let y2 = ; +let y3 = ; diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution11.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution11.tsx new file mode 100644 index 0000000000000..c80086234411c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution11.tsx @@ -0,0 +1,36 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const obj = {}; +const obj1: { x: 2 } = { + x: 2 +} +const obj3: {y: true, overwrite: string } = { + y: true, + overwrite: "hi" +} + +interface Prop { + x: 2 + y: true + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
Hello
; + } +} + +let anyobj: any; +// OK +let x = +let x1 = +let x2 = +let x3 = +let x4 = +let x5 = \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx new file mode 100644 index 0000000000000..b5150bd27ff1f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx @@ -0,0 +1,34 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const obj = {}; +const obj1: {x: 2} = { + x: 2 +} +const obj3: {y: false, overwrite: string} = { + y: false, + overwrite: "hi" +} + +interface Prop { + x: 2 + y: false + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
Hello
; + } +} + +let anyobj: any; + +// Error +let x = +let x1 = +let x2 = diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx new file mode 100644 index 0000000000000..1d647226adec0 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx @@ -0,0 +1,24 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: "2"; +} + +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +const obj = {}; + +// Error +let p = ; +let y = ; +let z = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution3.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution3.tsx new file mode 100644 index 0000000000000..8bff2abbd2c1f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution3.tsx @@ -0,0 +1,26 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: number; +} + +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +const obj = { + x: "hello world", + y: 2 +}; + +// OK +let p = ; +let y = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution4.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution4.tsx new file mode 100644 index 0000000000000..803853aacdb3b --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution4.tsx @@ -0,0 +1,25 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: 2; +} + +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +const obj: PoisonedProp = { + x: "hello world", + y: 2 +}; + +// OK +let p = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx new file mode 100644 index 0000000000000..76ff79149f348 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx @@ -0,0 +1,25 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: 2; +} + +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +let obj = { + x: "hello world", + y: 2 +}; + +// Error as "obj" has type { x: string; y: number } +let p = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution6.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution6.tsx new file mode 100644 index 0000000000000..35a190e10cc08 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution6.tsx @@ -0,0 +1,22 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + +class TextComponent extends React.Component { + render() { + return Some Text..; + } +} + +// Error +let x = + +const textProps: TextProps = { + editable: false +}; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution7.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution7.tsx new file mode 100644 index 0000000000000..55e3222c0221a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution7.tsx @@ -0,0 +1,29 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + +class TextComponent extends React.Component { + render() { + return Some Text..; + } +} + +// OK +const textPropsFalse: TextProps = { + editable: false +}; + +let y1 = + +const textPropsTrue: TextProps = { + editable: true, + onEdit: () => {} +}; + +let y2 = \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution8.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution8.tsx new file mode 100644 index 0000000000000..937678605d679 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution8.tsx @@ -0,0 +1,31 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +const obj = {}; +const obj1 = { + x: 2 +} +const obj3 = { + y: true, + overwrite: "hi" +} + +interface Prop { + x: number + y: boolean + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
Hello
; + } +} + +// OK +let x = +let x1 = \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution9.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution9.tsx new file mode 100644 index 0000000000000..9f2a63a56b6e7 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution9.tsx @@ -0,0 +1,29 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface OptionProp { + x?: 2 + y?: boolean +} + +class Opt extends React.Component { + render() { + return
Hello
; + } +} + +const obj: OptionProp = {}; +const obj1: OptionProp = { + x: 2 +} + +// OK +let p = ; +let y = ; +let y1 = ; +let y2 = ; +let y3 = ; \ No newline at end of file From 4dfe8e8067ac29fcdd9385eb0c58d7f0e5d634d0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:32:52 -0800 Subject: [PATCH 07/25] Add tests for using default attributes in JSX stateful component --- .../jsx/tsxDefaultAttributesResolution1.tsx | 18 ++++++++++++++++++ .../jsx/tsxDefaultAttributesResolution2.tsx | 18 ++++++++++++++++++ .../jsx/tsxDefaultAttributesResolution3.tsx | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 tests/cases/conformance/jsx/tsxDefaultAttributesResolution1.tsx create mode 100644 tests/cases/conformance/jsx/tsxDefaultAttributesResolution2.tsx create mode 100644 tests/cases/conformance/jsx/tsxDefaultAttributesResolution3.tsx diff --git a/tests/cases/conformance/jsx/tsxDefaultAttributesResolution1.tsx b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution1.tsx new file mode 100644 index 0000000000000..03314b400ee44 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution1.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + x: boolean; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// OK +let p = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxDefaultAttributesResolution2.tsx b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution2.tsx new file mode 100644 index 0000000000000..b00655b5a5717 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution2.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + x: true; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// OK +let p = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxDefaultAttributesResolution3.tsx b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution3.tsx new file mode 100644 index 0000000000000..303e6ef891d68 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxDefaultAttributesResolution3.tsx @@ -0,0 +1,18 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + x: false; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// Error +let p = ; \ No newline at end of file From 4f221d981de6688b99bf13766aa8db450ed5f5ac Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:33:25 -0800 Subject: [PATCH 08/25] Add tests for overload stateless function component --- ...tsxStatelessFunctionComponentOverload1.tsx | 44 +++++++++++++ ...tsxStatelessFunctionComponentOverload2.tsx | 37 +++++++++++ ...tsxStatelessFunctionComponentOverload3.tsx | 29 +++++++++ ...tsxStatelessFunctionComponentOverload4.tsx | 39 ++++++++++++ ...tsxStatelessFunctionComponentOverload5.tsx | 62 +++++++++++++++++++ ...tsxStatelessFunctionComponentOverload6.tsx | 62 +++++++++++++++++++ 6 files changed, 273 insertions(+) create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload1.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload1.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload1.tsx new file mode 100644 index 0000000000000..ea950d8b6d488 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload1.tsx @@ -0,0 +1,44 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +declare function OneThing(k: {yxx: string}): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string, yy2: boolean}): JSX.Element; +declare function OneThing(l1: {data: string, "data-prop": boolean}): JSX.Element; + +// OK +const c1 = +const c2 = +const c3 = +const c4 = + +declare function TestingOneThing({y1: string}): JSX.Element; +declare function TestingOneThing(j: {"extra-data": string, yy?: string}): JSX.Element; +declare function TestingOneThing(n: {yy: number, direction?: number}): JSX.Element; +declare function TestingOneThing(n: {yy: string, name: string}): JSX.Element; + +// OK +const d1 = ; +const d2 = ; +const d3 = ; +const d4 = ; +const d5 = ; + + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; + +// OK +const e1 = +const e2 = +const e3 = +const e4 = +const e5 = +const e6 = + + diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx new file mode 100644 index 0000000000000..fe2a3eb747772 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx @@ -0,0 +1,37 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') +declare function OneThing(): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; + +let obj = { + yy: 10, + yy1: "hello" +} + +let obj1 = { + yy: true +} + +let obj2 = { + yy: 500, + "ignore-prop": "hello" +} + +let defaultObj = undefined; + +// OK +const c1 = +const c2 = +const c3 = +const c4 = +const c5 = +const c6 = +const c7 = ; // No error. should pick second overload +const c8 = +const c9 = ; +const c10 = ; diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx new file mode 100644 index 0000000000000..5a21bcfe73675 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx @@ -0,0 +1,29 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +interface Context { + color: any; +} +declare function ZeroThingOrTwoThing(): JSX.Element; +declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; + +let obj2 = undefined; + +// OK +const two1 = ; +const two2 = ; +const two3 = ; // it is just any so we allow it to pass through +const two4 = ; // it is just any so we allow it to pass through +const two5 = ; // it is just any so we allow it to pass through + +declare function ThreeThing(l: {y1: string}): JSX.Element; +declare function ThreeThing(l: {y2: string}): JSX.Element; +declare function ThreeThing(l: {yy: number, yy1: string}, context: Context, updater: any): JSX.Element; + +// OK +const three1 = ; +const three2 = ; +const three3 = ; // it is just any so we allow it to pass through \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx new file mode 100644 index 0000000000000..d94c7a5531c48 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx @@ -0,0 +1,39 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') +declare function OneThing(): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; + +let obj = { + yy: 10, + yy1: "hello" +} +let obj2 = undefined; + +// Error +const c0 = ; // extra property; +const c1 = ; // missing property; +const c2 = ; // type incompatible; +const c3 = ; // Extra attribute; +const c4 = ; // extra property; +const c5 = ; // type incompatible; +const c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not +const c7 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + +declare function TestingOneThing(j: {"extra-data": string}): JSX.Element; +declare function TestingOneThing(n: {yy: string, direction?: number}): JSX.Element; + +// Error +const d1 = +const d2 = + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; + +// Error +const e1 = +const e2 = diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx new file mode 100644 index 0000000000000..8821d0adccec3 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx @@ -0,0 +1,62 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +export interface ClickableProps { + children?: string; + className?: string; +} + +export interface ButtonProps extends ClickableProps { + onClick: React.MouseEventHandler; +} + +export interface LinkProps extends ClickableProps { + to: string; +} + +export interface HyphenProps extends ClickableProps { + "data-format": string; +} + +let obj0 = { + to: "world" +}; + +let obj1 = { + children: "hi", + to: "boo" +} + +let obj2 = { + onClick: ()=>{} +} + +let obj3 = undefined; + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +export function MainButton(linkProps: LinkProps): JSX.Element; +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.to) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); +} + +// Error +const b0 = {}}>GO; // extra property; +const b1 = {}} {...obj0}>Hello world; // extra property; +const b2 = ; // extra property +const b3 = {}}} />; // extra property +const b4 = ; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed +const b5 = ; // Spread doesn't retain method declaration +const b6 = ; // incorrect type for optional attribute +const b7 = ; // incorrect type for optional attribute +const b8 = ; // incorrect type for specified hyphanted name \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx new file mode 100644 index 0000000000000..2bd372eaa0d44 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx @@ -0,0 +1,62 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +export interface ClickableProps { + children?: string; + className?: string; +} + +export interface ButtonProps extends ClickableProps { + onClick: React.MouseEventHandler; +} + +export interface LinkProps extends ClickableProps { + to: string; +} + +export interface HyphenProps extends ClickableProps { + "data-format": string; +} + +let obj = { + children: "hi", + to: "boo" +} +let obj1 = undefined; +let obj2 = { + onClick: () => {} +} + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +export function MainButton(linkProps: LinkProps): JSX.Element; +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.to) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); +} + +// OK +const b0 = GO; +const b1 = {}}>Hello world; +const b2 = ; +const b3 = ; +const b4 = ; // any; just pick the first overload +const b5 = ; // should pick the second overload +const b6 = ; +const b7 = { console.log("hi") }}} />; +const b8 = ; // OK; method declaration get discarded +const b9 = GO; +const b10 = GO; +const b11 = {}} className="hello" data-format>Hello world; +const b12 = + + From 3bd435fe5b07bba7d5f58d12236a09f3624891f8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:34:23 -0800 Subject: [PATCH 09/25] Add tests for generic stateless function component --- ...ssFunctionComponentsWithTypeArguments1.tsx | 45 +++++++++++++++++++ ...ssFunctionComponentsWithTypeArguments2.tsx | 27 +++++++++++ ...ssFunctionComponentsWithTypeArguments3.tsx | 29 ++++++++++++ ...ssFunctionComponentsWithTypeArguments4.tsx | 17 +++++++ 4 files changed, 118 insertions(+) create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments1.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments2.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments3.tsx create mode 100644 tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments4.tsx diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments1.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments1.tsx new file mode 100644 index 0000000000000..3cae847122968 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments1.tsx @@ -0,0 +1,45 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + + +declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; + +// OK +function Baz(key1: T, value: U) { + let a0 = + let a1 = +} + +// OK +declare function Component(l: U): JSX.Element; +function createComponent(arg:T) { + let a1 = ; + let a2 = ; +} + +declare function ComponentSpecific(l: {prop: U}): JSX.Element; +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; + +// OK +function Bar(arg: T) { + let a1 = ; // U is number + let a2 = ; // U is number + let a3 = ; // U is "hello" +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + +// OK +function createLink(func: (a: number)=>void) { + let o = +} + +function createLink1(func: (a: number)=>boolean) { + let o = +} + diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments2.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments2.tsx new file mode 100644 index 0000000000000..e264ffde2ff69 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments2.tsx @@ -0,0 +1,27 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": string}): JSX.Element; +declare function ComponentSpecific2(l: {prop: U}): JSX.Element; + +// Error +function Bar(arg: T) { + let a1 = ; + } + +// Error +function Baz(arg: T) { + let a0 = +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + +// Error +function createLink(func: (a: number, b: string)=>void) { + let o = +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments3.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments3.tsx new file mode 100644 index 0000000000000..68285c450c039 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments3.tsx @@ -0,0 +1,29 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +declare function OverloadComponent(): JSX.Element; +declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + +// OK +function Baz(arg1: T, arg2: U) { + let a0 = ; + let a1 = ; + let a2 = ; + let a3 = ; + let a4 = ; + let a5 = ; + let a6 = ; +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +declare function Link(l: {func: (arg1:U, arg2: string)=>void}): JSX.Element; +function createLink(func: (a: number)=>void) { + let o = + let o1 = {}} />; +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments4.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments4.tsx new file mode 100644 index 0000000000000..4be582dab5cd8 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments4.tsx @@ -0,0 +1,17 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +declare function OverloadComponent(): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: string, "ignore-prop": boolean}): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + +// Error +function Baz(arg1: T, arg2: U) { + let a0 = + let a2 = // missing a +} \ No newline at end of file From d73d2b846fc58d0f14eb9e6da8be7359e837c8a1 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 09:34:45 -0800 Subject: [PATCH 10/25] Add a test for contextual type in JSXAttributes --- ...lyTypedStringLiteralsInJsxAttributes02.tsx | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes02.tsx diff --git a/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes02.tsx b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes02.tsx new file mode 100644 index 0000000000000..918f4507e2a87 --- /dev/null +++ b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes02.tsx @@ -0,0 +1,42 @@ +// @filename: file.tsx +// @jsx: preserve +// @module: amd +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react') + +export interface ClickableProps { + children?: string; + className?: string; +} + +export interface ButtonProps extends ClickableProps { + onClick: (k: "left" | "right") => void; +} + +export interface LinkProps extends ClickableProps { + goTo: "home" | "contact"; +} + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +export function MainButton(linkProps: LinkProps): JSX.Element; +export function MainButton(props: ButtonProps | LinkProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.goTo) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); +} + +const b0 = {console.log(k)}}} extra />; // k has type any +const b2 = {console.log(k)}} extra />; // k has type "left" | "right" +const b3 = ; // goTo has type"home" | "contact" +const b4 = ; // goTo has type "home" | "contact" + +export function NoOverload(buttonProps: ButtonProps): JSX.Element { return undefined } +const c1 = {console.log(k)}}} extra />; // k has type any + +export function NoOverload1(linkProps: LinkProps): JSX.Element { return undefined } +const d1 = ; // goTo has type "home" | "contact" From c86290c03bf8cb87d89a443f725501a03ed83ff9 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 10:39:20 -0800 Subject: [PATCH 11/25] Update react.d.ts used during tests --- tests/lib/react.d.ts | 2024 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 1747 insertions(+), 277 deletions(-) diff --git a/tests/lib/react.d.ts b/tests/lib/react.d.ts index 0a3b0fdfabf9e..b2b0783cf1533 100644 --- a/tests/lib/react.d.ts +++ b/tests/lib/react.d.ts @@ -4,35 +4,51 @@ // Definitions: https://github.com/borisyankov/DefinitelyTyped declare namespace __React { + // // React Elements // ---------------------------------------------------------------------- type ReactType = string | ComponentClass | StatelessComponent; - interface ReactElement

> { - type: string | ComponentClass

| StatelessComponent

; + type Key = string | number; + type Ref = string | ((instance: T) => any); + type ComponentState = {} | void; + + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; props: P; - key: string | number; - ref: string | ((component: Component | Element) => any); + key?: Key; + } + + interface SFCElement

extends ReactElement

{ + type: SFC

; } - interface ClassicElement

extends ReactElement

{ - type: ClassicComponentClass

; - ref: string | ((component: ClassicComponent) => any); + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; } - interface DOMElement

> extends ReactElement

{ + type ClassicElement

= CElement>; + + interface DOMElement

, T extends Element> extends ReactElement

{ type: string; - ref: string | ((element: Element) => any); + ref: Ref; } - interface ReactHTMLElement extends DOMElement> { - ref: string | ((element: HTMLElement) => any); + interface ReactHTMLElement extends DOMElement, T> { } - interface ReactSVGElement extends DOMElement { - ref: string | ((element: SVGElement) => any); + interface ReactSVGElement extends DOMElement, SVGElement> { } // @@ -40,19 +56,29 @@ declare namespace __React { // ---------------------------------------------------------------------- interface Factory

{ - (props?: P, ...children: ReactNode[]): ReactElement

; + (props?: P & Attributes, ...children: ReactNode[]): ReactElement

; } - interface ClassicFactory

extends Factory

{ - (props?: P, ...children: ReactNode[]): ClassicElement

; + interface SFCFactory

{ + (props?: P & Attributes, ...children: ReactNode[]): SFCElement

; } - interface DOMFactory

> extends Factory

{ - (props?: P, ...children: ReactNode[]): DOMElement

; + interface ComponentFactory> { + (props?: P & ClassAttributes, ...children: ReactNode[]): CElement; } - type HTMLFactory = DOMFactory>; - type SVGFactory = DOMFactory; + type CFactory> = ComponentFactory; + type ClassicFactory

= CFactory>; + + interface DOMFactory

, T extends Element> { + (props?: P & ClassAttributes, ...children: ReactNode[]): DOMElement; + } + + interface HTMLFactory extends DOMFactory, T> { + } + + interface SVGFactory extends DOMFactory, SVGElement> { + } // // React Nodes @@ -72,41 +98,59 @@ declare namespace __React { function createClass(spec: ComponentSpec): ClassicComponentClass

; - function createFactory

(type: string): DOMFactory

; - function createFactory

(type: ClassicComponentClass

): ClassicFactory

; - function createFactory

(type: ComponentClass

| StatelessComponent

): Factory

; + function createFactory

, T extends Element>( + type: string): DOMFactory; + function createFactory

(type: SFC

): SFCFactory

; + function createFactory

( + type: ClassType, ClassicComponentClass

>): CFactory>; + function createFactory, C extends ComponentClass

>( + type: ClassType): CFactory; + function createFactory

(type: ComponentClass

| SFC

): Factory

; - function createElement

( + function createElement

, T extends Element>( type: string, - props?: P, - ...children: ReactNode[]): DOMElement

; + props?: P & ClassAttributes, + ...children: ReactNode[]): DOMElement; function createElement

( - type: ClassicComponentClass

, - props?: P, - ...children: ReactNode[]): ClassicElement

; + type: SFC

, + props?: P & Attributes, + ...children: ReactNode[]): SFCElement

; function createElement

( - type: ComponentClass

| StatelessComponent

, - props?: P, + type: ClassType, ClassicComponentClass

>, + props?: P & ClassAttributes>, + ...children: ReactNode[]): CElement>; + function createElement, C extends ComponentClass

>( + type: ClassType, + props?: P & ClassAttributes, + ...children: ReactNode[]): CElement; + function createElement

( + type: ComponentClass

| SFC

, + props?: P & Attributes, ...children: ReactNode[]): ReactElement

; - function cloneElement

( - element: DOMElement

, - props?: P, - ...children: ReactNode[]): DOMElement

; - function cloneElement

( - element: ClassicElement

, - props?: P, - ...children: ReactNode[]): ClassicElement

; - function cloneElement

( + function cloneElement

, T extends Element>( + element: DOMElement, + props?: P & ClassAttributes, + ...children: ReactNode[]): DOMElement; + function cloneElement

( + element: SFCElement

, + props?: Q, // should be Q & Attributes, but then Q is inferred as {} + ...children: ReactNode[]): SFCElement

; + function cloneElement

>( + element: CElement, + props?: Q, // should be Q & ClassAttributes + ...children: ReactNode[]): CElement; + function cloneElement

( element: ReactElement

, - props?: P, + props?: Q, // should be Q & Attributes ...children: ReactNode[]): ReactElement

; - function isValidElement(object: {}): boolean; + function isValidElement

(object: {}): object is ReactElement

; var DOM: ReactDOM; var PropTypes: ReactPropTypes; var Children: ReactChildren; + var version: string; // // Component API @@ -120,8 +164,14 @@ declare namespace __React { setState(f: (prevState: S, props: P) => S, callback?: () => any): void; setState(state: S, callback?: () => any): void; forceUpdate(callBack?: () => any): void; - render(): JSX.Element; - props: P; + render(): JSX.Element | null; + + // React.Props is now deprecated, which means that the `children` + // property is not available on `P` by default, even though you can + // always pass children as variadic arguments to `createElement`. + // In the future, if we can define its call signature conditionally + // on the existence of `children` in `P`, then we should remove this. + props: P & { children?: ReactNode }; state: S; context: {}; refs: { @@ -129,6 +179,8 @@ declare namespace __React { }; } + class PureComponent extends Component {} + interface ClassicComponent extends Component { replaceState(nextState: S, callback?: () => any): void; isMounted(): boolean; @@ -143,27 +195,39 @@ declare namespace __React { // Class Interfaces // ---------------------------------------------------------------------- + type SFC

= StatelessComponent

; interface StatelessComponent

{ - (props?: P, context?: any): ReactElement; + (props: P, context?: any): ReactElement; propTypes?: ValidationMap

; contextTypes?: ValidationMap; defaultProps?: P; + displayName?: string; } interface ComponentClass

{ - new(props?: P, context?: any): Component; + new(props?: P, context?: any): Component; propTypes?: ValidationMap

; contextTypes?: ValidationMap; childContextTypes?: ValidationMap; defaultProps?: P; + displayName?: string; } interface ClassicComponentClass

extends ComponentClass

{ - new(props?: P, context?: any): ClassicComponent; + new(props?: P, context?: any): ClassicComponent; getDefaultProps?(): P; - displayName?: string; } + /** + * We use an intersection type to infer multiple type parameters from + * a single argument, which is useful for many top-level API defs. + * See https://github.com/Microsoft/TypeScript/issues/7234 for more info. + */ + type ClassType, C extends ComponentClass

> = + C & + (new() => T) & + (new() => { props: P }); + // // Component Specs and Lifecycle // ---------------------------------------------------------------------- @@ -187,7 +251,7 @@ declare namespace __React { displayName?: string; propTypes?: ValidationMap; contextTypes?: ValidationMap; - childContextTypes?: ValidationMap + childContextTypes?: ValidationMap; getDefaultProps?(): P; getInitialState?(): S; @@ -203,41 +267,44 @@ declare namespace __React { // Event System // ---------------------------------------------------------------------- - interface SyntheticEvent { + interface SyntheticEvent { bubbles: boolean; + currentTarget: EventTarget & T; cancelable: boolean; - currentTarget: EventTarget; defaultPrevented: boolean; eventPhase: number; isTrusted: boolean; nativeEvent: Event; preventDefault(): void; + isDefaultPrevented(): boolean; stopPropagation(): void; + isPropagationStopped(): boolean; + persist(): void; target: EventTarget; timeStamp: Date; type: string; } - interface ClipboardEvent extends SyntheticEvent { + interface ClipboardEvent extends SyntheticEvent { clipboardData: DataTransfer; } - interface CompositionEvent extends SyntheticEvent { + interface CompositionEvent extends SyntheticEvent { data: string; } - interface DragEvent extends SyntheticEvent { + interface DragEvent extends MouseEvent { dataTransfer: DataTransfer; } - interface FocusEvent extends SyntheticEvent { + interface FocusEvent extends SyntheticEvent { relatedTarget: EventTarget; } - interface FormEvent extends SyntheticEvent { + interface FormEvent extends SyntheticEvent { } - interface KeyboardEvent extends SyntheticEvent { + interface KeyboardEvent extends SyntheticEvent { altKey: boolean; charCode: number; ctrlKey: boolean; @@ -252,7 +319,7 @@ declare namespace __React { which: number; } - interface MouseEvent extends SyntheticEvent { + interface MouseEvent extends SyntheticEvent { altKey: boolean; button: number; buttons: number; @@ -269,7 +336,7 @@ declare namespace __React { shiftKey: boolean; } - interface TouchEvent extends SyntheticEvent { + interface TouchEvent extends SyntheticEvent { altKey: boolean; changedTouches: TouchList; ctrlKey: boolean; @@ -280,178 +347,1577 @@ declare namespace __React { touches: TouchList; } - interface UIEvent extends SyntheticEvent { + interface UIEvent extends SyntheticEvent { detail: number; view: AbstractView; } - interface WheelEvent extends SyntheticEvent { + interface WheelEvent extends MouseEvent { deltaMode: number; deltaX: number; deltaY: number; deltaZ: number; } + interface AnimationEvent extends SyntheticEvent<{}> { + animationName: string; + pseudoElement: string; + elapsedTime: number; + } + + interface TransitionEvent extends SyntheticEvent<{}> { + propertyName: string; + pseudoElement: string; + elapsedTime: number; + } + // // Event Handler Types // ---------------------------------------------------------------------- - interface EventHandler { + interface EventHandler> { (event: E): void; } - type ReactEventHandler = EventHandler; - - type ClipboardEventHandler = EventHandler; - type CompositionEventHandler = EventHandler; - type DragEventHandler = EventHandler; - type FocusEventHandler = EventHandler; - type FormEventHandler = EventHandler; - type KeyboardEventHandler = EventHandler; - type MouseEventHandler = EventHandler; - type TouchEventHandler = EventHandler; - type UIEventHandler = EventHandler; - type WheelEventHandler = EventHandler; + type ReactEventHandler = EventHandler>; + + type ClipboardEventHandler = EventHandler>; + type CompositionEventHandler = EventHandler>; + type DragEventHandler = EventHandler>; + type FocusEventHandler = EventHandler>; + type FormEventHandler = EventHandler>; + type KeyboardEventHandler = EventHandler>; + type MouseEventHandler = EventHandler>; + type TouchEventHandler = EventHandler>; + type UIEventHandler = EventHandler>; + type WheelEventHandler = EventHandler>; + type AnimationEventHandler = EventHandler; + type TransitionEventHandler = EventHandler; // // Props / DOM Attributes // ---------------------------------------------------------------------- + /** + * @deprecated. This was used to allow clients to pass `ref` and `key` + * to `createElement`, which is no longer necessary due to intersection + * types. If you need to declare a props object before passing it to + * `createElement` or a factory, use `ClassAttributes`: + * + * ```ts + * var b: Button; + * var props: ButtonProps & ClassAttributes

; >div : Symbol(unknown) @@ -147,13 +147,13 @@ var x = /* a multi-line comment */ attr1="foo"> ->attr1 : Symbol(unknown) +>attr1 : Symbol(attr1, Decl(jsxReactTestSuite.tsx, 68, 6)) span : Symbol(unknown) attr2="bar" ->attr2 : Symbol(unknown) +>attr2 : Symbol(attr2, Decl(jsxReactTestSuite.tsx, 72, 9)) />
@@ -175,7 +175,7 @@ var x = ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) ->constructor : Symbol(unknown) +>constructor : Symbol(constructor, Decl(jsxReactTestSuite.tsx, 84, 10)) ; >Namespace : Symbol(Namespace, Decl(jsxReactTestSuite.tsx, 6, 11)) @@ -186,23 +186,23 @@ var x = Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) >x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 90, 20)) ={2 } z />; ->z : Symbol(unknown) +>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 91, 5)) Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) {...this.props} sound="moo" />; ->sound : Symbol(unknown) +>sound : Symbol(sound, Decl(jsxReactTestSuite.tsx, 94, 19)) ; >font-face : Symbol(unknown) ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 98, 10)) >y : Symbol(y, Decl(jsxReactTestSuite.tsx, 9, 11)) ; @@ -215,24 +215,24 @@ var x = ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) >x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 104, 19)) ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) >x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3)) ->y : Symbol(unknown) ->z : Symbol(unknown) +>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 106, 20)) +>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 106, 26)) ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 108, 10)) >y : Symbol(y, Decl(jsxReactTestSuite.tsx, 9, 11)) ; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 111, 10)) +>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 111, 16)) >z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11)) >z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11)) >Child : Symbol(Child, Decl(jsxReactTestSuite.tsx, 5, 11)) @@ -240,11 +240,11 @@ var x = Text; >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 113, 10)) >z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11)) >y : Symbol(y, Decl(jsxReactTestSuite.tsx, 113, 27)) >z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11)) ->z : Symbol(unknown) +>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 113, 39)) >Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) diff --git a/tests/baselines/reference/jsxReactTestSuite.types b/tests/baselines/reference/jsxReactTestSuite.types index 712a7368a622f..bd120ba9df232 100644 --- a/tests/baselines/reference/jsxReactTestSuite.types +++ b/tests/baselines/reference/jsxReactTestSuite.types @@ -116,7 +116,7 @@ var x = >div : any attr1={ ->attr1 : any +>attr1 : string "foo" + "bar" >"foo" + "bar" : string @@ -124,7 +124,7 @@ var x = >"bar" : "bar" } attr2={ ->attr2 : any +>attr2 : string "foo" + "bar" + >"foo" + "bar" + "baz" + "bug" : string @@ -138,7 +138,7 @@ var x = >"bug" : "bug" } attr3={ ->attr3 : any +>attr3 : string "foo" + "bar" + >"foo" + "bar" + "baz" + "bug" : string @@ -154,7 +154,7 @@ var x = // Extra line here. } attr4="baz"> ->attr4 : any +>attr4 : string
; >div : any @@ -198,14 +198,14 @@ var x = /* a multi-line comment */ attr1="foo"> ->attr1 : any +>attr1 : string : any >span : any attr2="bar" ->attr2 : any +>attr2 : string />
@@ -231,7 +231,7 @@ var x = ; > : any >Component : any ->constructor : any +>constructor : string ; > : any @@ -251,11 +251,11 @@ var x = > : any >Component : any >x : any ->y : any +>y : number ={2 } z />; >2 : 2 ->z : any +>z : true : any @@ -265,7 +265,7 @@ var x = >this.props : any >this : any >props : any ->sound : any +>sound : string ; > : any @@ -290,21 +290,21 @@ var x = > : any >Component : any >x : any ->y : any +>y : number >2 : 2 ; > : any >Component : any >x : any ->y : any +>y : number >2 : 2 ->z : any +>z : true ; > : any >Component : any ->x : any +>x : number >1 : 1 >y : any @@ -312,9 +312,9 @@ var x = ; > : any >Component : any ->x : any +>x : number >1 : 1 ->y : any +>y : string >z : any >z : any > : any @@ -324,7 +324,7 @@ var x = Text; >Text : any >Component : any ->x : any +>x : string >(z = { y: 2 }, z) : any >z = { y: 2 }, z : any >z = { y: 2 } : { y: number; } @@ -333,7 +333,7 @@ var x = >y : number >2 : 2 >z : any ->z : any +>z : number >3 : 3 >Component : any diff --git a/tests/baselines/reference/keywordInJsxIdentifier.symbols b/tests/baselines/reference/keywordInJsxIdentifier.symbols index 3cb977bee81d6..73ee737616440 100644 --- a/tests/baselines/reference/keywordInJsxIdentifier.symbols +++ b/tests/baselines/reference/keywordInJsxIdentifier.symbols @@ -5,17 +5,17 @@ declare var React: any; ; >foo : Symbol(unknown) ->class-id : Symbol(unknown) +>class-id : Symbol(class-id, Decl(keywordInJsxIdentifier.tsx, 2, 4)) ; >foo : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(keywordInJsxIdentifier.tsx, 3, 4)) ; >foo : Symbol(unknown) ->class-id : Symbol(unknown) +>class-id : Symbol(class-id, Decl(keywordInJsxIdentifier.tsx, 4, 4)) ; >foo : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(keywordInJsxIdentifier.tsx, 5, 4)) diff --git a/tests/baselines/reference/keywordInJsxIdentifier.types b/tests/baselines/reference/keywordInJsxIdentifier.types index 745fa5998b59a..0e4c4387cf47e 100644 --- a/tests/baselines/reference/keywordInJsxIdentifier.types +++ b/tests/baselines/reference/keywordInJsxIdentifier.types @@ -6,20 +6,20 @@ declare var React: any; ; > : any >foo : any ->class-id : any +>class-id : true ; > : any >foo : any ->class : any +>class : true ; > : any >foo : any ->class-id : any +>class-id : string ; > : any >foo : any ->class : any +>class : string diff --git a/tests/baselines/reference/reactNamespaceImportPresevation.symbols b/tests/baselines/reference/reactNamespaceImportPresevation.symbols index e2f530d31ba73..caeca7cefcb99 100644 --- a/tests/baselines/reference/reactNamespaceImportPresevation.symbols +++ b/tests/baselines/reference/reactNamespaceImportPresevation.symbols @@ -17,5 +17,5 @@ declare var foo: any; ; >foo : Symbol(unknown) ->data : Symbol(unknown) +>data : Symbol(data, Decl(test.tsx, 3, 4)) diff --git a/tests/baselines/reference/reactNamespaceImportPresevation.types b/tests/baselines/reference/reactNamespaceImportPresevation.types index adb1d60d2d5c9..931a86d248de0 100644 --- a/tests/baselines/reference/reactNamespaceImportPresevation.types +++ b/tests/baselines/reference/reactNamespaceImportPresevation.types @@ -18,5 +18,5 @@ declare var foo: any; ; > : any >foo : any ->data : any +>data : true diff --git a/tests/baselines/reference/reactNamespaceJSXEmit.symbols b/tests/baselines/reference/reactNamespaceJSXEmit.symbols index 3ca5b91e538d1..55aae09776cf7 100644 --- a/tests/baselines/reference/reactNamespaceJSXEmit.symbols +++ b/tests/baselines/reference/reactNamespaceJSXEmit.symbols @@ -14,11 +14,11 @@ declare var x: any; ; >foo : Symbol(unknown) ->data : Symbol(unknown) +>data : Symbol(data, Decl(reactNamespaceJSXEmit.tsx, 6, 4)) ; >Bar : Symbol(Bar, Decl(reactNamespaceJSXEmit.tsx, 3, 11)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(reactNamespaceJSXEmit.tsx, 7, 4)) >x : Symbol(x, Decl(reactNamespaceJSXEmit.tsx, 4, 11)) ; @@ -31,5 +31,5 @@ declare var x: any; ; >Bar : Symbol(Bar, Decl(reactNamespaceJSXEmit.tsx, 3, 11)) >x : Symbol(x, Decl(reactNamespaceJSXEmit.tsx, 4, 11)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(reactNamespaceJSXEmit.tsx, 10, 13)) diff --git a/tests/baselines/reference/reactNamespaceJSXEmit.types b/tests/baselines/reference/reactNamespaceJSXEmit.types index d2bd88e8fbd0e..0f6fbd6830942 100644 --- a/tests/baselines/reference/reactNamespaceJSXEmit.types +++ b/tests/baselines/reference/reactNamespaceJSXEmit.types @@ -15,7 +15,7 @@ declare var x: any; ; > : any >foo : any ->data : any +>data : true ; > : any @@ -36,6 +36,6 @@ declare var x: any; > : any >Bar : any >x : any ->y : any +>y : number >2 : 2 diff --git a/tests/baselines/reference/tsxAttributeErrors.errors.txt b/tests/baselines/reference/tsxAttributeErrors.errors.txt index 4a89896936363..50dfd88c52702 100644 --- a/tests/baselines/reference/tsxAttributeErrors.errors.txt +++ b/tests/baselines/reference/tsxAttributeErrors.errors.txt @@ -1,7 +1,12 @@ -tests/cases/conformance/jsx/tsxAttributeErrors.tsx(15,6): error TS2322: Type '42' is not assignable to type 'string'. -tests/cases/conformance/jsx/tsxAttributeErrors.tsx(18,6): error TS2322: Type '"foo"' is not assignable to type 'number'. -tests/cases/conformance/jsx/tsxAttributeErrors.tsx(22,6): error TS2606: Property 'text' of JSX spread attribute is not assignable to target property. - Type 'number' is not assignable to type 'string'. +tests/cases/conformance/jsx/tsxAttributeErrors.tsx(15,6): error TS2322: Type '{ text: 42; }' is not assignable to type '{ text?: string; width?: number; }'. + Types of property 'text' are incompatible. + Type '42' is not assignable to type 'string'. +tests/cases/conformance/jsx/tsxAttributeErrors.tsx(18,6): error TS2322: Type '{ width: "foo"; }' is not assignable to type '{ text?: string; width?: number; }'. + Types of property 'width' are incompatible. + Type '"foo"' is not assignable to type 'number'. +tests/cases/conformance/jsx/tsxAttributeErrors.tsx(22,6): error TS2322: Type '{ text: number; }' is not assignable to type '{ text?: string; width?: number; }'. + Types of property 'text' are incompatible. + Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/jsx/tsxAttributeErrors.tsx (3 errors) ==== @@ -21,19 +26,24 @@ tests/cases/conformance/jsx/tsxAttributeErrors.tsx(22,6): error TS2606: Property // Error, number is not assignable to string
; ~~~~~~~~~ -!!! error TS2322: Type '42' is not assignable to type 'string'. +!!! error TS2322: Type '{ text: 42; }' is not assignable to type '{ text?: string; width?: number; }'. +!!! error TS2322: Types of property 'text' are incompatible. +!!! error TS2322: Type '42' is not assignable to type 'string'. // Error, string is not assignable to number
; ~~~~~~~~~~~~~ -!!! error TS2322: Type '"foo"' is not assignable to type 'number'. +!!! error TS2322: Type '{ width: "foo"; }' is not assignable to type '{ text?: string; width?: number; }'. +!!! error TS2322: Types of property 'width' are incompatible. +!!! error TS2322: Type '"foo"' is not assignable to type 'number'. // Error, number is not assignable to string var attribs = { text: 100 };
; ~~~~~~~~~~~~ -!!! error TS2606: Property 'text' of JSX spread attribute is not assignable to target property. -!!! error TS2606: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Type '{ text: number; }' is not assignable to type '{ text?: string; width?: number; }'. +!!! error TS2322: Types of property 'text' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. // No errors here ; diff --git a/tests/baselines/reference/tsxAttributeResolution1.errors.txt b/tests/baselines/reference/tsxAttributeResolution1.errors.txt index f7fb114f3e0bc..d064f72f85d99 100644 --- a/tests/baselines/reference/tsxAttributeResolution1.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution1.errors.txt @@ -1,10 +1,20 @@ -tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type '"0"' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(24,8): error TS2339: Property 'y' does not exist on type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(25,8): error TS2339: Property 'y' does not exist on type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(26,8): error TS2322: Type '"32"' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(27,8): error TS2339: Property 'var' does not exist on type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(29,1): error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'. -tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '10' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type '{ x: "0"; }' is not assignable to type 'Attribs1'. + Types of property 'x' are incompatible. + Type '"0"' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(24,8): error TS2322: Type '{ y: 0; }' is not assignable to type 'Attribs1'. + Property 'y' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(25,8): error TS2322: Type '{ y: "foo"; }' is not assignable to type 'Attribs1'. + Property 'y' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(26,8): error TS2322: Type '{ x: "32"; }' is not assignable to type 'Attribs1'. + Types of property 'x' are incompatible. + Type '"32"' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(27,8): error TS2322: Type '{ var: "10"; }' is not assignable to type 'Attribs1'. + Property 'var' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(29,1): error TS2322: Type '{}' is not assignable to type '{ reqd: string; }'. + Property 'reqd' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '{ reqd: 10; }' is not assignable to type '{ reqd: string; }'. + Types of property 'reqd' are incompatible. + Type '10' is not assignable to type 'string'. ==== tests/cases/conformance/jsx/file.tsx (7 errors) ==== @@ -32,26 +42,36 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '10' is not assig // Errors ; // Error, '0' is not number ~~~~~~~ -!!! error TS2322: Type '"0"' is not assignable to type 'number'. +!!! error TS2322: Type '{ x: "0"; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '"0"' is not assignable to type 'number'. ; // Error, no property "y" - ~ -!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. + ~~~~~ +!!! error TS2322: Type '{ y: 0; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, no property "y" - ~ -!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. + ~~~~~~~ +!!! error TS2322: Type '{ y: "foo"; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, "32" is not number ~~~~~~ -!!! error TS2322: Type '"32"' is not assignable to type 'number'. +!!! error TS2322: Type '{ x: "32"; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '"32"' is not assignable to type 'number'. ; // Error, no 'var' property - ~~~ -!!! error TS2339: Property 'var' does not exist on type 'Attribs1'. + ~~~~~~~~ +!!! error TS2322: Type '{ var: "10"; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'var' does not exist on type 'Attribs1'. ; // Error, missing reqd ~~~~~~~~~ -!!! error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ reqd: string; }'. +!!! error TS2322: Property 'reqd' is missing in type '{}'. ; // Error, reqd is not string ~~~~~~~~~ -!!! error TS2322: Type '10' is not assignable to type 'string'. +!!! error TS2322: Type '{ reqd: 10; }' is not assignable to type '{ reqd: string; }'. +!!! error TS2322: Types of property 'reqd' are incompatible. +!!! error TS2322: Type '10' is not assignable to type 'string'. // Should be OK ; diff --git a/tests/baselines/reference/tsxAttributeResolution10.errors.txt b/tests/baselines/reference/tsxAttributeResolution10.errors.txt index 787eb4b5f0003..dce068dbb769d 100644 --- a/tests/baselines/reference/tsxAttributeResolution10.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution10.errors.txt @@ -1,4 +1,6 @@ -tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '"world"' is not assignable to type 'boolean'. +tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '{ bar: "world"; }' is not assignable to type '{ [s: string]: boolean; }'. + Property 'bar' is incompatible with index signature. + Type '"world"' is not assignable to type 'boolean'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -25,7 +27,9 @@ tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '"world"' is not // Should be an error ; ~~~~~~~~~~~ -!!! error TS2322: Type '"world"' is not assignable to type 'boolean'. +!!! error TS2322: Type '{ bar: "world"; }' is not assignable to type '{ [s: string]: boolean; }'. +!!! error TS2322: Property 'bar' is incompatible with index signature. +!!! error TS2322: Type '"world"' is not assignable to type 'boolean'. // Should be OK ; diff --git a/tests/baselines/reference/tsxAttributeResolution11.errors.txt b/tests/baselines/reference/tsxAttributeResolution11.errors.txt index b043897d50d0a..a46bf4ba16fe0 100644 --- a/tests/baselines/reference/tsxAttributeResolution11.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution11.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. +tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. + Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -27,7 +28,8 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does n // Should be an OK var x = ; - ~~~ -!!! error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. + ~~~~~~~~~~~ +!!! error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. +!!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution12.errors.txt b/tests/baselines/reference/tsxAttributeResolution12.errors.txt index ecf51a0f3dd48..041776814ca93 100644 --- a/tests/baselines/reference/tsxAttributeResolution12.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution12.errors.txt @@ -1,5 +1,9 @@ -tests/cases/conformance/jsx/file.tsx(26,10): error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'. -tests/cases/conformance/jsx/file.tsx(29,10): error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'. +tests/cases/conformance/jsx/file.tsx(26,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'. + Type '{}' is not assignable to type '{ reqd: any; }'. + Property 'reqd' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(29,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'. + Type '{}' is not assignable to type '{ reqd: any; }'. + Property 'reqd' is missing in type '{}'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -44,11 +48,15 @@ tests/cases/conformance/jsx/file.tsx(29,10): error TS2324: Property 'reqd' is mi const T = TestMod.Test; var t1 = ; ~~~~~ -!!! error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'. +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ reqd: any; }'. +!!! error TS2322: Property 'reqd' is missing in type '{}'. // Should error var t2 = ; ~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'. +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ reqd: any; }'. +!!! error TS2322: Property 'reqd' is missing in type '{}'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution14.errors.txt b/tests/baselines/reference/tsxAttributeResolution14.errors.txt index 9f4e00747f1e7..79b4a55f10245 100644 --- a/tests/baselines/reference/tsxAttributeResolution14.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution14.errors.txt @@ -1,5 +1,9 @@ -tests/cases/conformance/jsx/file.tsx(14,28): error TS2322: Type '2' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(16,28): error TS2322: Type 'true' is not assignable to type 'string | number'. +tests/cases/conformance/jsx/file.tsx(14,28): error TS2322: Type '{ primaryText: 2; }' is not assignable to type 'IProps'. + Types of property 'primaryText' are incompatible. + Type '2' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(16,28): error TS2322: Type '{ justRandomProp1: true; primaryText: "hello"; }' is not assignable to type 'IProps'. + Property 'justRandomProp1' is incompatible with index signature. + Type 'true' is not assignable to type 'string | number'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -28,11 +32,15 @@ tests/cases/conformance/jsx/file.tsx(16,28): error TS2322: Type 'true' is not as
// error ~~~~~~~~~~~~~~~ -!!! error TS2322: Type '2' is not assignable to type 'string'. +!!! error TS2322: Type '{ primaryText: 2; }' is not assignable to type 'IProps'. +!!! error TS2322: Types of property 'primaryText' are incompatible. +!!! error TS2322: Type '2' is not assignable to type 'string'. // ok // error - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'true' is not assignable to type 'string | number'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ justRandomProp1: true; primaryText: "hello"; }' is not assignable to type 'IProps'. +!!! error TS2322: Property 'justRandomProp1' is incompatible with index signature. +!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
) } \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution3.errors.txt b/tests/baselines/reference/tsxAttributeResolution3.errors.txt index ae8ba7a9a5470..dd4ef78652a0b 100644 --- a/tests/baselines/reference/tsxAttributeResolution3.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution3.errors.txt @@ -1,9 +1,13 @@ -tests/cases/conformance/jsx/file.tsx(19,8): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(23,1): error TS2324: Property 'x' is missing in type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(31,15): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(39,8): error TS2322: Type '32' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(19,8): error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'. + Types of property 'x' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. + Property 'x' is missing in type '{ y: number; }'. +tests/cases/conformance/jsx/file.tsx(31,8): error TS2322: Type '{ x: number; y: number; }' is not assignable to type 'Attribs1'. + Types of property 'x' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(35,8): error TS2322: Type '{ x: string; y: number; extra: number; }' is not assignable to type 'Attribs1'. + Property 'extra' does not exist on type 'Attribs1'. ==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== @@ -27,14 +31,16 @@ tests/cases/conformance/jsx/file.tsx(39,8): error TS2322: Type '32' is not assig var obj2 = { x: 32 }; ~~~~~~~~~ -!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. -!!! error TS2606: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Type '{ x: number; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. // Error, x is missing var obj3 = { y: 32 }; - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + ~~~~~~~~~ +!!! error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'x' is missing in type '{ y: number; }'. // OK var obj4 = { x: 32, y: 32 }; @@ -43,17 +49,19 @@ tests/cases/conformance/jsx/file.tsx(39,8): error TS2322: Type '32' is not assig // Error var obj5 = { x: 32, y: 32 }; - ~~~~~~~~~ -!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. -!!! error TS2606: Type 'number' is not assignable to type 'string'. + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: number; y: number; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. // OK var obj6 = { x: 'ok', y: 32, extra: 100 }; + ~~~~~~~~~ +!!! error TS2322: Type '{ x: string; y: number; extra: number; }' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'extra' does not exist on type 'Attribs1'. - // Error + // OK (spread override) var obj7 = { x: 'foo' }; - ~~~~~~ -!!! error TS2322: Type '32' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution3.js b/tests/baselines/reference/tsxAttributeResolution3.js index 2898a6bc25144..9605002936e21 100644 --- a/tests/baselines/reference/tsxAttributeResolution3.js +++ b/tests/baselines/reference/tsxAttributeResolution3.js @@ -35,7 +35,7 @@ var obj5 = { x: 32, y: 32 }; var obj6 = { x: 'ok', y: 32, extra: 100 }; -// Error +// OK (spread override) var obj7 = { x: 'foo' }; @@ -59,6 +59,6 @@ var obj5 = { x: 32, y: 32 }; // OK var obj6 = { x: 'ok', y: 32, extra: 100 }; ; -// Error +// OK (spread override) var obj7 = { x: 'foo' }; ; diff --git a/tests/baselines/reference/tsxAttributeResolution5.errors.txt b/tests/baselines/reference/tsxAttributeResolution5.errors.txt index 42dabc741ab92..ffbd41a07b25a 100644 --- a/tests/baselines/reference/tsxAttributeResolution5.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution5.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/jsx/file.tsx(21,16): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(25,9): error TS2324: Property 'x' is missing in type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(29,1): error TS2324: Property 'x' is missing in type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(30,1): error TS2324: Property 'toString' is missing in type 'Attribs2'. +tests/cases/conformance/jsx/file.tsx(17,16): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(21,16): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(25,16): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(29,8): error TS2322: Type '{}' is not assignable to type 'Attribs1'. + Property 'x' is missing in type '{}'. ==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== @@ -23,26 +23,26 @@ tests/cases/conformance/jsx/file.tsx(30,1): error TS2324: Property 'toString' is function make1 (obj: T) { return ; // OK + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. } function make2 (obj: T) { return ; // Error (x is number, not string) ~~~~~~~~ -!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property. -!!! error TS2606: Type 'number' is not assignable to type 'string'. +!!! error TS2698: Spread types may only be created from object types. } function make3 (obj: T) { return ; // Error, missing x - ~~~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. } ; // Error, missing x - ~~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + ~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'Attribs1'. +!!! error TS2322: Property 'x' is missing in type '{}'. ; // Error, missing toString - ~~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'toString' is missing in type 'Attribs2'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution6.errors.txt b/tests/baselines/reference/tsxAttributeResolution6.errors.txt index f3a4d512152da..77f1f5bb8df7a 100644 --- a/tests/baselines/reference/tsxAttributeResolution6.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution6.errors.txt @@ -1,6 +1,11 @@ -tests/cases/conformance/jsx/file.tsx(10,8): error TS2322: Type 'boolean' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(11,8): error TS2322: Type '"true"' is not assignable to type 'boolean'. -tests/cases/conformance/jsx/file.tsx(12,1): error TS2324: Property 'n' is missing in type '{ n: boolean; }'. +tests/cases/conformance/jsx/file.tsx(10,8): error TS2322: Type '{ s: true; }' is not assignable to type '{ n?: boolean; s?: string; }'. + Types of property 's' are incompatible. + Type 'true' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(11,8): error TS2322: Type '{ n: "true"; }' is not assignable to type '{ n?: boolean; s?: string; }'. + Types of property 'n' are incompatible. + Type '"true"' is not assignable to type 'boolean'. +tests/cases/conformance/jsx/file.tsx(12,1): error TS2322: Type '{}' is not assignable to type '{ n: boolean; }'. + Property 'n' is missing in type '{}'. ==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== @@ -15,13 +20,18 @@ tests/cases/conformance/jsx/file.tsx(12,1): error TS2324: Property 'n' is missin // Error ; ~ -!!! error TS2322: Type 'boolean' is not assignable to type 'string'. +!!! error TS2322: Type '{ s: true; }' is not assignable to type '{ n?: boolean; s?: string; }'. +!!! error TS2322: Types of property 's' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'string'. ; ~~~~~~~~ -!!! error TS2322: Type '"true"' is not assignable to type 'boolean'. +!!! error TS2322: Type '{ n: "true"; }' is not assignable to type '{ n?: boolean; s?: string; }'. +!!! error TS2322: Types of property 'n' are incompatible. +!!! error TS2322: Type '"true"' is not assignable to type 'boolean'. ; ~~~~~~~~~ -!!! error TS2324: Property 'n' is missing in type '{ n: boolean; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ n: boolean; }'. +!!! error TS2322: Property 'n' is missing in type '{}'. // OK ; diff --git a/tests/baselines/reference/tsxAttributeResolution7.errors.txt b/tests/baselines/reference/tsxAttributeResolution7.errors.txt index f5af1b48eb2aa..6f379f9dc1e48 100644 --- a/tests/baselines/reference/tsxAttributeResolution7.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution7.errors.txt @@ -1,4 +1,6 @@ -tests/cases/conformance/jsx/file.tsx(9,8): error TS2322: Type '32' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(9,8): error TS2322: Type '{ data-foo: 32; }' is not assignable to type '{ "data-foo"?: string; }'. + Types of property '"data-foo"' are incompatible. + Type '32' is not assignable to type 'string'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -12,7 +14,9 @@ tests/cases/conformance/jsx/file.tsx(9,8): error TS2322: Type '32' is not assign // Error ; ~~~~~~~~~~~~~ -!!! error TS2322: Type '32' is not assignable to type 'string'. +!!! error TS2322: Type '{ data-foo: 32; }' is not assignable to type '{ "data-foo"?: string; }'. +!!! error TS2322: Types of property '"data-foo"' are incompatible. +!!! error TS2322: Type '32' is not assignable to type 'string'. // OK ; diff --git a/tests/baselines/reference/tsxAttributeResolution9.errors.txt b/tests/baselines/reference/tsxAttributeResolution9.errors.txt index 73571689b1fa3..670cdd6dfcb47 100644 --- a/tests/baselines/reference/tsxAttributeResolution9.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution9.errors.txt @@ -1,4 +1,6 @@ -tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '0' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '{ foo: 0; }' is not assignable to type '{ foo: string; }'. + Types of property 'foo' are incompatible. + Type '0' is not assignable to type 'string'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -27,5 +29,7 @@ tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '0' is not assign ; // ok ; // should be an error ~~~~~~~ -!!! error TS2322: Type '0' is not assignable to type 'string'. +!!! error TS2322: Type '{ foo: 0; }' is not assignable to type '{ foo: string; }'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type '0' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution1.js b/tests/baselines/reference/tsxDefaultAttributesResolution1.js new file mode 100644 index 0000000000000..1bb12e56e9899 --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution1.js @@ -0,0 +1,36 @@ +//// [file.tsx] + +import React = require('react'); + +interface Prop { + x: boolean; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// OK +let p = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
Hello
; + }; + return Poisoned; +}(React.Component)); +// OK +var p = ; diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols new file mode 100644 index 0000000000000..a0efe4f9dbe31 --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution1.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface Prop { +>Prop : Symbol(Prop, Decl(file.tsx, 1, 32)) + + x: boolean; +>x : Symbol(Prop.x, Decl(file.tsx, 3, 16)) +} +class Poisoned extends React.Component { +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 5, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>Prop : Symbol(Prop, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(Poisoned.render, Decl(file.tsx, 6, 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)) + } +} + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 13, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 5, 1)) +>x : Symbol(x, Decl(file.tsx, 13, 17)) + diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution1.types b/tests/baselines/reference/tsxDefaultAttributesResolution1.types new file mode 100644 index 0000000000000..1734380a55dde --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution1.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +interface Prop { +>Prop : Prop + + x: boolean; +>x : boolean +} +class Poisoned extends React.Component { +>Poisoned : Poisoned +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>Prop : Prop + + render() { +>render : () => JSX.Element + + return
Hello
; +>
Hello
: JSX.Element +>div : any +>div : any + } +} + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>x : true + diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution2.js b/tests/baselines/reference/tsxDefaultAttributesResolution2.js new file mode 100644 index 0000000000000..d94b592d1346e --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution2.js @@ -0,0 +1,36 @@ +//// [file.tsx] + +import React = require('react'); + +interface Prop { + x: true; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// OK +let p = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
Hello
; + }; + return Poisoned; +}(React.Component)); +// OK +var p = ; diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols new file mode 100644 index 0000000000000..7bcdc7ccfa20d --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution2.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface Prop { +>Prop : Symbol(Prop, Decl(file.tsx, 1, 32)) + + x: true; +>x : Symbol(Prop.x, Decl(file.tsx, 3, 16)) +} +class Poisoned extends React.Component { +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 5, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>Prop : Symbol(Prop, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(Poisoned.render, Decl(file.tsx, 6, 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)) + } +} + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 13, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 5, 1)) +>x : Symbol(x, Decl(file.tsx, 13, 17)) + diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution2.types b/tests/baselines/reference/tsxDefaultAttributesResolution2.types new file mode 100644 index 0000000000000..ab2bc0c7da6e4 --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution2.types @@ -0,0 +1,36 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +interface Prop { +>Prop : Prop + + x: true; +>x : true +>true : true +} +class Poisoned extends React.Component { +>Poisoned : Poisoned +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>Prop : Prop + + render() { +>render : () => JSX.Element + + return
Hello
; +>
Hello
: JSX.Element +>div : any +>div : any + } +} + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>x : true + diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution3.errors.txt b/tests/baselines/reference/tsxDefaultAttributesResolution3.errors.txt new file mode 100644 index 0000000000000..bfb780d202407 --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution3.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/jsx/file.tsx(14,19): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. + Type '{ x: true; }' is not assignable to type 'Prop'. + Types of property 'x' are incompatible. + Type 'true' is not assignable to type 'false'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + + import React = require('react'); + + interface Prop { + x: false; + } + class Poisoned extends React.Component { + render() { + return
Hello
; + } + } + + // Error + let p = ; + ~ +!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: true; }' is not assignable to type 'Prop'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'false'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxDefaultAttributesResolution3.js b/tests/baselines/reference/tsxDefaultAttributesResolution3.js new file mode 100644 index 0000000000000..db518997c57e8 --- /dev/null +++ b/tests/baselines/reference/tsxDefaultAttributesResolution3.js @@ -0,0 +1,36 @@ +//// [file.tsx] + +import React = require('react'); + +interface Prop { + x: false; +} +class Poisoned extends React.Component { + render() { + return
Hello
; + } +} + +// Error +let p = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
Hello
; + }; + return Poisoned; +}(React.Component)); +// Error +var p = ; diff --git a/tests/baselines/reference/tsxElementResolution.symbols b/tests/baselines/reference/tsxElementResolution.symbols index 729c3fc9f067c..4b3fd175e1961 100644 --- a/tests/baselines/reference/tsxElementResolution.symbols +++ b/tests/baselines/reference/tsxElementResolution.symbols @@ -32,7 +32,7 @@ module Dotted { var a = ; >a : Symbol(a, Decl(tsxElementResolution.tsx, 17, 3)) >foundFirst : Symbol(JSX.IntrinsicElements.foundFirst, Decl(tsxElementResolution.tsx, 2, 30)) ->x : Symbol(x, Decl(tsxElementResolution.tsx, 3, 15)) +>x : Symbol(x, Decl(tsxElementResolution.tsx, 17, 19)) var b = ; >b : Symbol(b, Decl(tsxElementResolution.tsx, 18, 3)) diff --git a/tests/baselines/reference/tsxElementResolution.types b/tests/baselines/reference/tsxElementResolution.types index a1c2abcef7c5f..891ebc37e5d60 100644 --- a/tests/baselines/reference/tsxElementResolution.types +++ b/tests/baselines/reference/tsxElementResolution.types @@ -33,7 +33,7 @@ var a = ; >a : any > : any >foundFirst : typeof foundFirst ->x : any +>x : string var b = ; >b : any diff --git a/tests/baselines/reference/tsxElementResolution11.errors.txt b/tests/baselines/reference/tsxElementResolution11.errors.txt index f6a4913e558e6..f0d5cf1e009a6 100644 --- a/tests/baselines/reference/tsxElementResolution11.errors.txt +++ b/tests/baselines/reference/tsxElementResolution11.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(17,7): error TS2339: Property 'x' does not exist on type '{ q?: number; }'. +tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'. + Property 'x' does not exist on type '{ q?: number; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -19,8 +20,9 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2339: Property 'x' does not } var Obj2: Obj2type; ; // Error - ~ -!!! error TS2339: Property 'x' does not exist on type '{ q?: number; }'. + ~~~~~~ +!!! error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'. +!!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'. interface Obj3type { new(n: string): { x: number; }; diff --git a/tests/baselines/reference/tsxElementResolution12.errors.txt b/tests/baselines/reference/tsxElementResolution12.errors.txt index 5367e29e388bd..5c4c9baf9cd15 100644 --- a/tests/baselines/reference/tsxElementResolution12.errors.txt +++ b/tests/baselines/reference/tsxElementResolution12.errors.txt @@ -1,9 +1,10 @@ -tests/cases/conformance/jsx/file.tsx(17,2): error TS2304: Cannot find name 'Obj2'. tests/cases/conformance/jsx/file.tsx(23,1): error TS2607: JSX element class does not support attributes because it does not have a 'pr' property -tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '"10"' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '{ x: "10"; }' is not assignable to type '{ x: number; }'. + Types of property 'x' are incompatible. + Type '"10"' is not assignable to type 'number'. -==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== declare module JSX { interface Element { } interface ElementAttributesProperty { pr: any; } @@ -19,10 +20,8 @@ tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '"10"' is not ass interface Obj2type { new(n: string): { q?: number; pr: any }; } - var obj2: Obj2type; + var Obj2: Obj2type; ; // OK - ~~~~ -!!! error TS2304: Cannot find name 'Obj2'. interface Obj3type { new(n: string): { x: number; }; @@ -39,5 +38,7 @@ tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '"10"' is not ass ; // OK ; // Error ~~~~~~~~ -!!! error TS2322: Type '"10"' is not assignable to type 'number'. +!!! error TS2322: Type '{ x: "10"; }' is not assignable to type '{ x: number; }'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '"10"' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution12.js b/tests/baselines/reference/tsxElementResolution12.js index b4dd94ef0eb8b..b01266aa78984 100644 --- a/tests/baselines/reference/tsxElementResolution12.js +++ b/tests/baselines/reference/tsxElementResolution12.js @@ -14,7 +14,7 @@ var Obj1: Obj1type; interface Obj2type { new(n: string): { q?: number; pr: any }; } -var obj2: Obj2type; +var Obj2: Obj2type; ; // OK interface Obj3type { @@ -34,7 +34,7 @@ var Obj4: Obj4type; //// [file.jsx] var Obj1; ; // OK -var obj2; +var Obj2; ; // OK var Obj3; ; // Error diff --git a/tests/baselines/reference/tsxElementResolution13.symbols b/tests/baselines/reference/tsxElementResolution13.symbols index 9122f553a88d3..e306faeaaf261 100644 --- a/tests/baselines/reference/tsxElementResolution13.symbols +++ b/tests/baselines/reference/tsxElementResolution13.symbols @@ -23,5 +23,5 @@ var obj1: Obj1; ; // Error >obj1 : Symbol(unknown) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 9, 5)) diff --git a/tests/baselines/reference/tsxElementResolution13.types b/tests/baselines/reference/tsxElementResolution13.types index d55d4705ff419..b2a6e54633ab4 100644 --- a/tests/baselines/reference/tsxElementResolution13.types +++ b/tests/baselines/reference/tsxElementResolution13.types @@ -24,6 +24,6 @@ var obj1: Obj1; ; // Error > : JSX.Element >obj1 : Obj1 ->x : any +>x : number >10 : 10 diff --git a/tests/baselines/reference/tsxElementResolution14.symbols b/tests/baselines/reference/tsxElementResolution14.symbols index a605606b1ed50..e1a17239e85be 100644 --- a/tests/baselines/reference/tsxElementResolution14.symbols +++ b/tests/baselines/reference/tsxElementResolution14.symbols @@ -18,5 +18,5 @@ var obj1: Obj1; ; // OK >obj1 : Symbol(unknown) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 8, 5)) diff --git a/tests/baselines/reference/tsxElementResolution14.types b/tests/baselines/reference/tsxElementResolution14.types index 752a0baafb996..a6e8cc5283475 100644 --- a/tests/baselines/reference/tsxElementResolution14.types +++ b/tests/baselines/reference/tsxElementResolution14.types @@ -19,6 +19,6 @@ var obj1: Obj1; ; // OK > : JSX.Element >obj1 : Obj1 ->x : any +>x : number >10 : 10 diff --git a/tests/baselines/reference/tsxElementResolution3.errors.txt b/tests/baselines/reference/tsxElementResolution3.errors.txt index 1b8b6c5834c15..d869821a4cbd9 100644 --- a/tests/baselines/reference/tsxElementResolution3.errors.txt +++ b/tests/baselines/reference/tsxElementResolution3.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/jsx/file.tsx(12,1): error TS2324: Property 'n' is missing in type '{ n: string; }'. -tests/cases/conformance/jsx/file.tsx(12,7): error TS2339: Property 'w' does not exist on type '{ n: string; }'. +tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: "err"; }' is not assignable to type '{ n: string; }'. + Property 'w' does not exist on type '{ n: string; }'. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== declare module JSX { interface Element { } interface IntrinsicElements { @@ -15,7 +15,6 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2339: Property 'w' does not // Error ; - ~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'n' is missing in type '{ n: string; }'. - ~ -!!! error TS2339: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file + ~~~~~~~ +!!! error TS2322: Type '{ w: "err"; }' is not assignable to type '{ n: string; }'. +!!! error TS2322: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution4.errors.txt b/tests/baselines/reference/tsxElementResolution4.errors.txt index e6dd599defc8d..b5d5437d87220 100644 --- a/tests/baselines/reference/tsxElementResolution4.errors.txt +++ b/tests/baselines/reference/tsxElementResolution4.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/jsx/file.tsx(16,1): error TS2324: Property 'm' is missing in type '{ m: string; }'. -tests/cases/conformance/jsx/file.tsx(16,7): error TS2339: Property 'q' does not exist on type '{ m: string; }'. +tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: ""; }' is not assignable to type '{ m: string; }'. + Property 'q' does not exist on type '{ m: string; }'. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== declare module JSX { interface Element { } interface IntrinsicElements { @@ -19,8 +19,7 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2339: Property 'q' does not // Error ; - ~~~~~~~~~~~~~ -!!! error TS2324: Property 'm' is missing in type '{ m: string; }'. - ~ -!!! error TS2339: Property 'q' does not exist on type '{ m: string; }'. + ~~~~ +!!! error TS2322: Type '{ q: ""; }' is not assignable to type '{ m: string; }'. +!!! error TS2322: Property 'q' does not exist on type '{ m: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution5.symbols b/tests/baselines/reference/tsxElementResolution5.symbols index e0fc11470837e..a788a51fc65e8 100644 --- a/tests/baselines/reference/tsxElementResolution5.symbols +++ b/tests/baselines/reference/tsxElementResolution5.symbols @@ -9,5 +9,5 @@ declare module JSX { // OK, but implicit any
; >div : Symbol(unknown) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file1.tsx, 5, 4)) diff --git a/tests/baselines/reference/tsxElementResolution5.types b/tests/baselines/reference/tsxElementResolution5.types index cdfb91c706728..cd2f3d2633784 100644 --- a/tests/baselines/reference/tsxElementResolution5.types +++ b/tests/baselines/reference/tsxElementResolution5.types @@ -10,5 +10,5 @@ declare module JSX {
; >
: JSX.Element >div : any ->n : any +>n : string diff --git a/tests/baselines/reference/tsxElementResolution9.symbols b/tests/baselines/reference/tsxElementResolution9.symbols index d6b0da12e6f37..30193ebb82d7b 100644 --- a/tests/baselines/reference/tsxElementResolution9.symbols +++ b/tests/baselines/reference/tsxElementResolution9.symbols @@ -64,5 +64,5 @@ var Obj3: Obj3; ; // OK >Obj3 : Symbol(Obj3, Decl(file.tsx, 17, 9), Decl(file.tsx, 23, 3)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 24, 5)) diff --git a/tests/baselines/reference/tsxElementResolution9.types b/tests/baselines/reference/tsxElementResolution9.types index c63e61efc0716..4d9fb4e73e9fa 100644 --- a/tests/baselines/reference/tsxElementResolution9.types +++ b/tests/baselines/reference/tsxElementResolution9.types @@ -67,6 +67,6 @@ var Obj3: Obj3; ; // OK > : JSX.Element >Obj3 : Obj3 ->x : any +>x : number >42 : 42 diff --git a/tests/baselines/reference/tsxEmit1.symbols b/tests/baselines/reference/tsxEmit1.symbols index 9e32354b1844c..f86c40d2c0752 100644 --- a/tests/baselines/reference/tsxEmit1.symbols +++ b/tests/baselines/reference/tsxEmit1.symbols @@ -23,37 +23,37 @@ var selfClosed1 =
; var selfClosed2 =
; >selfClosed2 : Symbol(selfClosed2, Decl(file.tsx, 9, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 9, 22)) var selfClosed3 =
; >selfClosed3 : Symbol(selfClosed3, Decl(file.tsx, 10, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 10, 22)) var selfClosed4 =
; >selfClosed4 : Symbol(selfClosed4, Decl(file.tsx, 11, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 11, 22)) +>y : Symbol(y, Decl(file.tsx, 11, 28)) var selfClosed5 =
; >selfClosed5 : Symbol(selfClosed5, Decl(file.tsx, 12, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 12, 22)) +>y : Symbol(y, Decl(file.tsx, 12, 28)) var selfClosed6 =
; >selfClosed6 : Symbol(selfClosed6, Decl(file.tsx, 13, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 13, 22)) +>y : Symbol(y, Decl(file.tsx, 13, 30)) var selfClosed7 =
; >selfClosed7 : Symbol(selfClosed7, Decl(file.tsx, 14, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 14, 22)) >p : Symbol(p, Decl(file.tsx, 7, 3)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(file.tsx, 14, 28)) var openClosed1 =
; >openClosed1 : Symbol(openClosed1, Decl(file.tsx, 16, 3)) @@ -63,20 +63,20 @@ var openClosed1 =
; var openClosed2 =
foo
; >openClosed2 : Symbol(openClosed2, Decl(file.tsx, 17, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 17, 22)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var openClosed3 =
{p}
; >openClosed3 : Symbol(openClosed3, Decl(file.tsx, 18, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 18, 22)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var openClosed4 =
{p < p}
; >openClosed4 : Symbol(openClosed4, Decl(file.tsx, 19, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 19, 22)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) @@ -84,7 +84,7 @@ var openClosed4 =
{p < p}
; var openClosed5 =
{p > p}
; >openClosed5 : Symbol(openClosed5, Decl(file.tsx, 20, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 20, 22)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) @@ -118,14 +118,14 @@ class SomeClass { var rewrites4 =
this}>
; >rewrites4 : Symbol(rewrites4, Decl(file.tsx, 28, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 28, 22)) >this : Symbol(SomeClass, Decl(file.tsx, 20, 43)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var rewrites5 =
; >rewrites5 : Symbol(rewrites5, Decl(file.tsx, 29, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 29, 22)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >p : Symbol(p, Decl(file.tsx, 7, 3)) >p : Symbol(p, Decl(file.tsx, 7, 3)) @@ -134,7 +134,7 @@ class SomeClass { var rewrites6 =
; >rewrites6 : Symbol(rewrites6, Decl(file.tsx, 30, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 30, 22)) >p : Symbol(p, Decl(file.tsx, 30, 27)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) } diff --git a/tests/baselines/reference/tsxEmit1.types b/tests/baselines/reference/tsxEmit1.types index c3ca7a2b1b015..e6b19a535a455 100644 --- a/tests/baselines/reference/tsxEmit1.types +++ b/tests/baselines/reference/tsxEmit1.types @@ -25,44 +25,44 @@ var selfClosed2 =
; >selfClosed2 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string var selfClosed3 =
; >selfClosed3 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string var selfClosed4 =
; >selfClosed4 : JSX.Element >
: JSX.Element >div : any ->x : any ->y : any +>x : string +>y : string var selfClosed5 =
; >selfClosed5 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : number >0 : 0 ->y : any +>y : string var selfClosed6 =
; >selfClosed6 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string >"1" : "1" ->y : any +>y : string var selfClosed7 =
; >selfClosed7 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : undefined >p : undefined ->y : any +>y : string var openClosed1 =
; >openClosed1 : JSX.Element @@ -74,14 +74,14 @@ var openClosed2 =
foo
; >openClosed2 : JSX.Element >
foo
: JSX.Element >div : any ->n : any +>n : string >div : any var openClosed3 =
{p}
; >openClosed3 : JSX.Element >
{p}
: JSX.Element >div : any ->n : any +>n : string >p : undefined >div : any @@ -89,7 +89,7 @@ var openClosed4 =
{p < p}
; >openClosed4 : JSX.Element >
{p < p}
: JSX.Element >div : any ->n : any +>n : string >p < p : boolean >p : undefined >p : undefined @@ -99,7 +99,7 @@ var openClosed5 =
{p > p}
; >openClosed5 : JSX.Element >
{p > p}
: JSX.Element >div : any ->n : any +>n : string >p > p : boolean >p : undefined >p : undefined @@ -142,7 +142,7 @@ class SomeClass { >rewrites4 : JSX.Element >
this}>
: JSX.Element >div : any ->a : any +>a : () => this >() => this : () => this >this : this >div : any @@ -151,7 +151,7 @@ class SomeClass { >rewrites5 : JSX.Element >
: JSX.Element >div : any ->a : any +>a : any[] >[p, ...p, p] : any[] >p : any >...p : any @@ -163,7 +163,7 @@ class SomeClass { >rewrites6 : JSX.Element >
: JSX.Element >div : any ->a : any +>a : { p: any; } >{p} : { p: any; } >p : any >div : any diff --git a/tests/baselines/reference/tsxEmit2.js b/tests/baselines/reference/tsxEmit2.js index 66b1494e8256b..d22f5bab9f1c4 100644 --- a/tests/baselines/reference/tsxEmit2.js +++ b/tests/baselines/reference/tsxEmit2.js @@ -6,7 +6,7 @@ declare module JSX { } } -var p1, p2, p3; +var p1: any, p2: any, p3: any; var spreads1 =
{p2}
; var spreads2 =
{p2}
; var spreads3 =
{p2}
; diff --git a/tests/baselines/reference/tsxEmit2.symbols b/tests/baselines/reference/tsxEmit2.symbols index 13e45e454f176..40b778253e960 100644 --- a/tests/baselines/reference/tsxEmit2.symbols +++ b/tests/baselines/reference/tsxEmit2.symbols @@ -13,51 +13,51 @@ declare module JSX { } } -var p1, p2, p3; +var p1: any, p2: any, p3: any; >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) ->p3 : Symbol(p3, Decl(file.tsx, 7, 11)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) +>p3 : Symbol(p3, Decl(file.tsx, 7, 21)) var spreads1 =
{p2}
; >spreads1 : Symbol(spreads1, Decl(file.tsx, 8, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads2 =
{p2}
; >spreads2 : Symbol(spreads2, Decl(file.tsx, 9, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads3 =
{p2}
; >spreads3 : Symbol(spreads3, Decl(file.tsx, 10, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 7, 11)) +>x : Symbol(x, Decl(file.tsx, 10, 19)) +>p3 : Symbol(p3, Decl(file.tsx, 7, 21)) >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads4 =
{p2}
; >spreads4 : Symbol(spreads4, Decl(file.tsx, 11, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->x : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 7, 11)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>x : Symbol(x, Decl(file.tsx, 11, 27)) +>p3 : Symbol(p3, Decl(file.tsx, 7, 21)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads5 =
{p2}
; >spreads5 : Symbol(spreads5, Decl(file.tsx, 12, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>x : Symbol(x, Decl(file.tsx, 12, 19)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >p1 : Symbol(p1, Decl(file.tsx, 7, 3)) ->y : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 7, 11)) ->p2 : Symbol(p2, Decl(file.tsx, 7, 7)) +>y : Symbol(y, Decl(file.tsx, 12, 34)) +>p3 : Symbol(p3, Decl(file.tsx, 7, 21)) +>p2 : Symbol(p2, Decl(file.tsx, 7, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) diff --git a/tests/baselines/reference/tsxEmit2.types b/tests/baselines/reference/tsxEmit2.types index d306dc9ffe057..e02dc6c7f8620 100644 --- a/tests/baselines/reference/tsxEmit2.types +++ b/tests/baselines/reference/tsxEmit2.types @@ -13,7 +13,7 @@ declare module JSX { } } -var p1, p2, p3; +var p1: any, p2: any, p3: any; >p1 : any >p2 : any >p3 : any @@ -22,16 +22,16 @@ var spreads1 =
{p2}
; >spreads1 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined ->p2 : undefined +>p1 : any +>p2 : any >div : any var spreads2 =
{p2}
; >spreads2 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined ->p2 : undefined +>p1 : any +>p2 : any >div : any var spreads3 =
{p2}
; @@ -39,19 +39,19 @@ var spreads3 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p3 : undefined ->p1 : undefined ->p2 : undefined +>p3 : any +>p1 : any +>p2 : any >div : any var spreads4 =
{p2}
; >spreads4 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined +>p1 : any >x : any ->p3 : undefined ->p2 : undefined +>p3 : any +>p2 : any >div : any var spreads5 =
{p2}
; @@ -59,10 +59,10 @@ var spreads5 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p2 : undefined ->p1 : undefined +>p2 : any +>p1 : any >y : any ->p3 : undefined ->p2 : undefined +>p3 : any +>p2 : any >div : any diff --git a/tests/baselines/reference/tsxExternalModuleEmit2.symbols b/tests/baselines/reference/tsxExternalModuleEmit2.symbols index ff5fdc4917137..8f7cfa521361c 100644 --- a/tests/baselines/reference/tsxExternalModuleEmit2.symbols +++ b/tests/baselines/reference/tsxExternalModuleEmit2.symbols @@ -19,7 +19,7 @@ declare var Foo, React; // Should see mod_1['default'] in emit here ; >Foo : Symbol(Foo, Decl(app.tsx, 1, 11)) ->handler : Symbol(unknown) +>handler : Symbol(handler, Decl(app.tsx, 3, 4)) >Main : Symbol(Main, Decl(app.tsx, 0, 6)) >Foo : Symbol(Foo, Decl(app.tsx, 1, 11)) diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols index 2d3c1f18d48d2..8b773c3b5ab79 100644 --- a/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols @@ -44,7 +44,7 @@ x3(); var x4 = () => {}; >x4 : Symbol(x4, Decl(file.tsx, 19, 3)) >T : Symbol(T, Decl(file.tsx, 4, 3)) ->extends : Symbol(unknown) +>extends : Symbol(extends, Decl(file.tsx, 19, 11)) >T : Symbol(T, Decl(file.tsx, 4, 3)) x4.isElement; @@ -56,7 +56,7 @@ x4.isElement; var x5 = () => {}; >x5 : Symbol(x5, Decl(file.tsx, 23, 3)) >T : Symbol(T, Decl(file.tsx, 4, 3)) ->extends : Symbol(unknown) +>extends : Symbol(extends, Decl(file.tsx, 23, 11)) >T : Symbol(T, Decl(file.tsx, 4, 3)) x5.isElement; diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.types b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types index 0f746a071363e..0e601daecafa9 100644 --- a/tests/baselines/reference/tsxGenericArrowFunctionParsing.types +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types @@ -50,7 +50,7 @@ var x4 = () => {}; >x4 : JSX.Element >() => {} : JSX.Element >T : any ->extends : any +>extends : boolean >true : true >T : any @@ -64,7 +64,7 @@ var x5 = () => {}; >x5 : JSX.Element >() => {} : JSX.Element >T : any ->extends : any +>extends : true >T : any x5.isElement; diff --git a/tests/baselines/reference/tsxInArrowFunction.symbols b/tests/baselines/reference/tsxInArrowFunction.symbols index ff80428cf7438..9fc928e36e1e4 100644 --- a/tests/baselines/reference/tsxInArrowFunction.symbols +++ b/tests/baselines/reference/tsxInArrowFunction.symbols @@ -23,7 +23,7 @@ declare namespace JSX {
{() =>
}
; >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) ->text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 12, 16)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) // didn't work @@ -31,21 +31,21 @@ declare namespace JSX { >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) >x : Symbol(x, Decl(tsxInArrowFunction.tsx, 15, 6)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) ->text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 15, 15)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) // worked
{() => (
)}
; >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) ->text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 18, 17)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) // worked (!)
{() =>
}
; >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) ->text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 21, 16)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) >div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) diff --git a/tests/baselines/reference/tsxInArrowFunction.types b/tests/baselines/reference/tsxInArrowFunction.types index e4b2aeb50fe2c..76b0d1e1e6482 100644 --- a/tests/baselines/reference/tsxInArrowFunction.types +++ b/tests/baselines/reference/tsxInArrowFunction.types @@ -26,7 +26,7 @@ declare namespace JSX { >() =>
: () => JSX.Element >
: JSX.Element >div : any ->text : any +>text : string >div : any // didn't work @@ -37,7 +37,7 @@ declare namespace JSX { >x : any >
: JSX.Element >div : any ->text : any +>text : string >div : any // worked @@ -48,7 +48,7 @@ declare namespace JSX { >(
) : JSX.Element >
: JSX.Element >div : any ->text : any +>text : string >div : any // worked (!) @@ -58,7 +58,7 @@ declare namespace JSX { >() =>
: () => JSX.Element >
: JSX.Element >div : any ->text : any +>text : string >div : any >div : any diff --git a/tests/baselines/reference/tsxReactEmit1.symbols b/tests/baselines/reference/tsxReactEmit1.symbols index 6887a9550c086..ec4c367b40e69 100644 --- a/tests/baselines/reference/tsxReactEmit1.symbols +++ b/tests/baselines/reference/tsxReactEmit1.symbols @@ -25,38 +25,38 @@ var selfClosed1 =
; var selfClosed2 =
; >selfClosed2 : Symbol(selfClosed2, Decl(file.tsx, 10, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 10, 22)) var selfClosed3 =
; >selfClosed3 : Symbol(selfClosed3, Decl(file.tsx, 11, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 11, 22)) var selfClosed4 =
; >selfClosed4 : Symbol(selfClosed4, Decl(file.tsx, 12, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 12, 22)) +>y : Symbol(y, Decl(file.tsx, 12, 28)) var selfClosed5 =
; >selfClosed5 : Symbol(selfClosed5, Decl(file.tsx, 13, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 13, 22)) +>y : Symbol(y, Decl(file.tsx, 13, 28)) var selfClosed6 =
; >selfClosed6 : Symbol(selfClosed6, Decl(file.tsx, 14, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->y : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 14, 22)) +>y : Symbol(y, Decl(file.tsx, 14, 30)) var selfClosed7 =
; >selfClosed7 : Symbol(selfClosed7, Decl(file.tsx, 15, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(file.tsx, 15, 22)) >p : Symbol(p, Decl(file.tsx, 8, 3)) ->y : Symbol(unknown) ->b : Symbol(unknown) +>y : Symbol(y, Decl(file.tsx, 15, 28)) +>b : Symbol(b, Decl(file.tsx, 15, 34)) var openClosed1 =
; >openClosed1 : Symbol(openClosed1, Decl(file.tsx, 17, 3)) @@ -66,20 +66,20 @@ var openClosed1 =
; var openClosed2 =
foo
; >openClosed2 : Symbol(openClosed2, Decl(file.tsx, 18, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 18, 22)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var openClosed3 =
{p}
; >openClosed3 : Symbol(openClosed3, Decl(file.tsx, 19, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 19, 22)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var openClosed4 =
{p < p}
; >openClosed4 : Symbol(openClosed4, Decl(file.tsx, 20, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 20, 22)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) @@ -87,8 +87,8 @@ var openClosed4 =
{p < p}
; var openClosed5 =
{p > p}
; >openClosed5 : Symbol(openClosed5, Decl(file.tsx, 21, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->n : Symbol(unknown) ->b : Symbol(unknown) +>n : Symbol(n, Decl(file.tsx, 21, 22)) +>b : Symbol(b, Decl(file.tsx, 21, 28)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) @@ -122,14 +122,14 @@ class SomeClass { var rewrites4 =
this}>
; >rewrites4 : Symbol(rewrites4, Decl(file.tsx, 29, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 29, 22)) >this : Symbol(SomeClass, Decl(file.tsx, 21, 45)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var rewrites5 =
; >rewrites5 : Symbol(rewrites5, Decl(file.tsx, 30, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 30, 22)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >p : Symbol(p, Decl(file.tsx, 8, 3)) >p : Symbol(p, Decl(file.tsx, 8, 3)) @@ -138,7 +138,7 @@ class SomeClass { var rewrites6 =
; >rewrites6 : Symbol(rewrites6, Decl(file.tsx, 31, 5)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->a : Symbol(unknown) +>a : Symbol(a, Decl(file.tsx, 31, 22)) >p : Symbol(p, Decl(file.tsx, 31, 27)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) } diff --git a/tests/baselines/reference/tsxReactEmit1.types b/tests/baselines/reference/tsxReactEmit1.types index b2cb2f73eba05..f2b0e9346324a 100644 --- a/tests/baselines/reference/tsxReactEmit1.types +++ b/tests/baselines/reference/tsxReactEmit1.types @@ -27,45 +27,45 @@ var selfClosed2 =
; >selfClosed2 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string var selfClosed3 =
; >selfClosed3 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string var selfClosed4 =
; >selfClosed4 : JSX.Element >
: JSX.Element >div : any ->x : any ->y : any +>x : string +>y : string var selfClosed5 =
; >selfClosed5 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : number >0 : 0 ->y : any +>y : string var selfClosed6 =
; >selfClosed6 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : string >"1" : "1" ->y : any +>y : string var selfClosed7 =
; >selfClosed7 : JSX.Element >
: JSX.Element >div : any ->x : any +>x : undefined >p : undefined ->y : any ->b : any +>y : string +>b : true var openClosed1 =
; >openClosed1 : JSX.Element @@ -77,14 +77,14 @@ var openClosed2 =
foo
; >openClosed2 : JSX.Element >
foo
: JSX.Element >div : any ->n : any +>n : string >div : any var openClosed3 =
{p}
; >openClosed3 : JSX.Element >
{p}
: JSX.Element >div : any ->n : any +>n : string >p : undefined >div : any @@ -92,7 +92,7 @@ var openClosed4 =
{p < p}
; >openClosed4 : JSX.Element >
{p < p}
: JSX.Element >div : any ->n : any +>n : string >p < p : boolean >p : undefined >p : undefined @@ -102,8 +102,8 @@ var openClosed5 =
{p > p}
; >openClosed5 : JSX.Element >
{p > p}
: JSX.Element >div : any ->n : any ->b : any +>n : string +>b : true >p > p : boolean >p : undefined >p : undefined @@ -146,7 +146,7 @@ class SomeClass { >rewrites4 : JSX.Element >
this}>
: JSX.Element >div : any ->a : any +>a : () => this >() => this : () => this >this : this >div : any @@ -155,7 +155,7 @@ class SomeClass { >rewrites5 : JSX.Element >
: JSX.Element >div : any ->a : any +>a : any[] >[p, ...p, p] : any[] >p : any >...p : any @@ -167,7 +167,7 @@ class SomeClass { >rewrites6 : JSX.Element >
: JSX.Element >div : any ->a : any +>a : { p: any; } >{p} : { p: any; } >p : any >div : any diff --git a/tests/baselines/reference/tsxReactEmit2.js b/tests/baselines/reference/tsxReactEmit2.js index 80e3215e2b6b1..c81c7b2afeae5 100644 --- a/tests/baselines/reference/tsxReactEmit2.js +++ b/tests/baselines/reference/tsxReactEmit2.js @@ -7,7 +7,7 @@ declare module JSX { } declare var React: any; -var p1, p2, p3; +var p1: any, p2: any, p3: any; var spreads1 =
{p2}
; var spreads2 =
{p2}
; var spreads3 =
{p2}
; diff --git a/tests/baselines/reference/tsxReactEmit2.symbols b/tests/baselines/reference/tsxReactEmit2.symbols index 68f33a11f091f..28b2c427bd8a4 100644 --- a/tests/baselines/reference/tsxReactEmit2.symbols +++ b/tests/baselines/reference/tsxReactEmit2.symbols @@ -15,51 +15,51 @@ declare module JSX { declare var React: any; >React : Symbol(React, Decl(file.tsx, 6, 11)) -var p1, p2, p3; +var p1: any, p2: any, p3: any; >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) ->p3 : Symbol(p3, Decl(file.tsx, 8, 11)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) +>p3 : Symbol(p3, Decl(file.tsx, 8, 21)) var spreads1 =
{p2}
; >spreads1 : Symbol(spreads1, Decl(file.tsx, 9, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads2 =
{p2}
; >spreads2 : Symbol(spreads2, Decl(file.tsx, 10, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads3 =
{p2}
; >spreads3 : Symbol(spreads3, Decl(file.tsx, 11, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 8, 11)) +>x : Symbol(x, Decl(file.tsx, 11, 19)) +>p3 : Symbol(p3, Decl(file.tsx, 8, 21)) >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads4 =
{p2}
; >spreads4 : Symbol(spreads4, Decl(file.tsx, 12, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->x : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 8, 11)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>x : Symbol(x, Decl(file.tsx, 12, 27)) +>p3 : Symbol(p3, Decl(file.tsx, 8, 21)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) var spreads5 =
{p2}
; >spreads5 : Symbol(spreads5, Decl(file.tsx, 13, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->x : Symbol(unknown) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>x : Symbol(x, Decl(file.tsx, 13, 19)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >p1 : Symbol(p1, Decl(file.tsx, 8, 3)) ->y : Symbol(unknown) ->p3 : Symbol(p3, Decl(file.tsx, 8, 11)) ->p2 : Symbol(p2, Decl(file.tsx, 8, 7)) +>y : Symbol(y, Decl(file.tsx, 13, 34)) +>p3 : Symbol(p3, Decl(file.tsx, 8, 21)) +>p2 : Symbol(p2, Decl(file.tsx, 8, 12)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) diff --git a/tests/baselines/reference/tsxReactEmit2.types b/tests/baselines/reference/tsxReactEmit2.types index b05764e996fc3..60599eb568f3a 100644 --- a/tests/baselines/reference/tsxReactEmit2.types +++ b/tests/baselines/reference/tsxReactEmit2.types @@ -15,7 +15,7 @@ declare module JSX { declare var React: any; >React : any -var p1, p2, p3; +var p1: any, p2: any, p3: any; >p1 : any >p2 : any >p3 : any @@ -24,16 +24,16 @@ var spreads1 =
{p2}
; >spreads1 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined ->p2 : undefined +>p1 : any +>p2 : any >div : any var spreads2 =
{p2}
; >spreads2 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined ->p2 : undefined +>p1 : any +>p2 : any >div : any var spreads3 =
{p2}
; @@ -41,19 +41,19 @@ var spreads3 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p3 : undefined ->p1 : undefined ->p2 : undefined +>p3 : any +>p1 : any +>p2 : any >div : any var spreads4 =
{p2}
; >spreads4 : JSX.Element >
{p2}
: JSX.Element >div : any ->p1 : undefined +>p1 : any >x : any ->p3 : undefined ->p2 : undefined +>p3 : any +>p2 : any >div : any var spreads5 =
{p2}
; @@ -61,10 +61,10 @@ var spreads5 =
{p2}
; >
{p2}
: JSX.Element >div : any >x : any ->p2 : undefined ->p1 : undefined +>p2 : any +>p1 : any >y : any ->p3 : undefined ->p2 : undefined +>p3 : any +>p2 : any >div : any diff --git a/tests/baselines/reference/tsxReactEmit4.errors.txt b/tests/baselines/reference/tsxReactEmit4.errors.txt index 23578d4ed91a4..1ac5b6a17b97d 100644 --- a/tests/baselines/reference/tsxReactEmit4.errors.txt +++ b/tests/baselines/reference/tsxReactEmit4.errors.txt @@ -10,7 +10,7 @@ tests/cases/conformance/jsx/file.tsx(12,5): error TS2304: Cannot find name 'blah } declare var React: any; - var p; + var p: any; var openClosed1 =
{blah} diff --git a/tests/baselines/reference/tsxReactEmit4.js b/tests/baselines/reference/tsxReactEmit4.js index 33c835d1ab22c..a1e790873e88e 100644 --- a/tests/baselines/reference/tsxReactEmit4.js +++ b/tests/baselines/reference/tsxReactEmit4.js @@ -7,7 +7,7 @@ declare module JSX { } declare var React: any; -var p; +var p: any; var openClosed1 =
{blah} diff --git a/tests/baselines/reference/tsxReactEmit5.js b/tests/baselines/reference/tsxReactEmit5.js index c3e58d0a0da54..2f180dc3af3e8 100644 --- a/tests/baselines/reference/tsxReactEmit5.js +++ b/tests/baselines/reference/tsxReactEmit5.js @@ -16,7 +16,7 @@ export var React; import {React} from "./test"; // Should emit test_1.React.createElement // and React.__spread -var foo; +var foo: any; var spread1 =
; diff --git a/tests/baselines/reference/tsxReactEmit5.symbols b/tests/baselines/reference/tsxReactEmit5.symbols index 3e0e17906761d..533652b0d3c5f 100644 --- a/tests/baselines/reference/tsxReactEmit5.symbols +++ b/tests/baselines/reference/tsxReactEmit5.symbols @@ -24,13 +24,13 @@ import {React} from "./test"; // Should emit test_1.React.createElement // and React.__spread -var foo; +var foo: any; >foo : Symbol(foo, Decl(react-consumer.tsx, 3, 3)) var spread1 =
; >spread1 : Symbol(spread1, Decl(react-consumer.tsx, 4, 3)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(react-consumer.tsx, 4, 18)) >foo : Symbol(foo, Decl(react-consumer.tsx, 3, 3)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(react-consumer.tsx, 4, 32)) diff --git a/tests/baselines/reference/tsxReactEmit5.types b/tests/baselines/reference/tsxReactEmit5.types index 73e7e6ff3913e..fb5e201ca3665 100644 --- a/tests/baselines/reference/tsxReactEmit5.types +++ b/tests/baselines/reference/tsxReactEmit5.types @@ -24,14 +24,14 @@ import {React} from "./test"; // Should emit test_1.React.createElement // and React.__spread -var foo; +var foo: any; >foo : any var spread1 =
; >spread1 : JSX.Element >
: JSX.Element >div : any ->x : any ->foo : undefined ->y : any +>x : string +>foo : any +>y : string diff --git a/tests/baselines/reference/tsxReactEmit6.js b/tests/baselines/reference/tsxReactEmit6.js index 85aa8c123c99c..fb76a2e1579b3 100644 --- a/tests/baselines/reference/tsxReactEmit6.js +++ b/tests/baselines/reference/tsxReactEmit6.js @@ -17,7 +17,7 @@ namespace M { namespace M { // Should emit M.React.createElement // and M.React.__spread - var foo; + var foo: any; var spread1 =
; // Quotes diff --git a/tests/baselines/reference/tsxReactEmit6.symbols b/tests/baselines/reference/tsxReactEmit6.symbols index 8eb0561e185fc..eeae4493b4ff9 100644 --- a/tests/baselines/reference/tsxReactEmit6.symbols +++ b/tests/baselines/reference/tsxReactEmit6.symbols @@ -27,15 +27,15 @@ namespace M { // Should emit M.React.createElement // and M.React.__spread - var foo; + var foo: any; >foo : Symbol(foo, Decl(react-consumer.tsx, 7, 4)) var spread1 =
; >spread1 : Symbol(spread1, Decl(react-consumer.tsx, 8, 4)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) ->x : Symbol(unknown) +>x : Symbol(x, Decl(react-consumer.tsx, 8, 19)) >foo : Symbol(foo, Decl(react-consumer.tsx, 7, 4)) ->y : Symbol(unknown) +>y : Symbol(y, Decl(react-consumer.tsx, 8, 33)) // Quotes var x =
This "quote" thing
; diff --git a/tests/baselines/reference/tsxReactEmit6.types b/tests/baselines/reference/tsxReactEmit6.types index ae56de052cc44..7cf08b8f0f5b8 100644 --- a/tests/baselines/reference/tsxReactEmit6.types +++ b/tests/baselines/reference/tsxReactEmit6.types @@ -27,16 +27,16 @@ namespace M { // Should emit M.React.createElement // and M.React.__spread - var foo; + var foo: any; >foo : any var spread1 =
; >spread1 : JSX.Element >
: JSX.Element >div : any ->x : any ->foo : undefined ->y : any +>x : string +>foo : any +>y : string // Quotes var x =
This "quote" thing
; diff --git a/tests/baselines/reference/tsxReactEmitEntities.symbols b/tests/baselines/reference/tsxReactEmitEntities.symbols index 470c6177842db..edb7f038c7b7d 100644 --- a/tests/baselines/reference/tsxReactEmitEntities.symbols +++ b/tests/baselines/reference/tsxReactEmitEntities.symbols @@ -35,18 +35,18 @@ declare var React: any; // Also works in string literal attributes
; >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->attr : Symbol(unknown) +>attr : Symbol(attr, Decl(file.tsx, 15, 4)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) // Does not happen for a string literal that happens to be inside an attribute (and escapes then work)
; >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->attr : Symbol(unknown) +>attr : Symbol(attr, Decl(file.tsx, 17, 4)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) // Preserves single quotes
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) ->attr : Symbol(unknown) +>attr : Symbol(attr, Decl(file.tsx, 19, 4)) >div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22)) diff --git a/tests/baselines/reference/tsxReactEmitEntities.types b/tests/baselines/reference/tsxReactEmitEntities.types index 34ef6dff0a867..92d2b729dd552 100644 --- a/tests/baselines/reference/tsxReactEmitEntities.types +++ b/tests/baselines/reference/tsxReactEmitEntities.types @@ -40,14 +40,14 @@ declare var React: any;
; >
: JSX.Element >div : any ->attr : any +>attr : string >div : any // Does not happen for a string literal that happens to be inside an attribute (and escapes then work)
; >
: JSX.Element >div : any ->attr : any +>attr : string >"{…}\"" : "{…}\"" >div : any @@ -55,6 +55,6 @@ declare var React: any;
>
: JSX.Element >div : any ->attr : any +>attr : string >div : any diff --git a/tests/baselines/reference/tsxReactEmitNesting.symbols b/tests/baselines/reference/tsxReactEmitNesting.symbols index efccb60274703..caf2425491e68 100644 --- a/tests/baselines/reference/tsxReactEmitNesting.symbols +++ b/tests/baselines/reference/tsxReactEmitNesting.symbols @@ -17,11 +17,11 @@ let render = (ctrl, model) =>
>section : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 7, 12))
>header : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 8, 15))

todos <x>

>h1 : Symbol(unknown) @@ -29,13 +29,13 @@ let render = (ctrl, model) => >input : Symbol(unknown) ->class : Symbol(unknown) ->autofocus : Symbol(unknown) ->autocomplete : Symbol(unknown) ->placeholder : Symbol(unknown) ->value : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 10, 18)) +>autofocus : Symbol(autofocus, Decl(file.tsx, 10, 35)) +>autocomplete : Symbol(autocomplete, Decl(file.tsx, 10, 45)) +>placeholder : Symbol(placeholder, Decl(file.tsx, 10, 64)) +>value : Symbol(value, Decl(file.tsx, 10, 101)) >model : Symbol(model, Decl(file.tsx, 6, 19)) ->onKeyup : Symbol(unknown) +>onKeyup : Symbol(onKeyup, Decl(file.tsx, 10, 123)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >model : Symbol(model, Decl(file.tsx, 6, 19)) @@ -45,23 +45,23 @@ let render = (ctrl, model) =>
>section : Symbol(unknown) ->class : Symbol(unknown) ->style : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 12, 16)) +>style : Symbol(style, Decl(file.tsx, 12, 29)) >display : Symbol(display, Decl(file.tsx, 12, 38)) >model : Symbol(model, Decl(file.tsx, 6, 19)) >model : Symbol(model, Decl(file.tsx, 6, 19)) >input : Symbol(unknown) ->class : Symbol(unknown) ->type : Symbol(unknown) ->onChange : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 13, 18)) +>type : Symbol(type, Decl(file.tsx, 13, 37)) +>onChange : Symbol(onChange, Decl(file.tsx, 13, 53)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14))
    >ul : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 14, 15)) {model.filteredTodos.map((todo) => >model : Symbol(model, Decl(file.tsx, 6, 19)) @@ -69,7 +69,7 @@ let render = (ctrl, model) =>
  • >li : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 16, 23)) >todo : Symbol(todo, Decl(file.tsx, 16, 32)) >completed : Symbol(completed, Decl(file.tsx, 16, 43)) >todo : Symbol(todo, Decl(file.tsx, 15, 42)) @@ -79,22 +79,22 @@ let render = (ctrl, model) =>
    >div : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 17, 28)) {(!todo.editable) ? >todo : Symbol(todo, Decl(file.tsx, 15, 42)) >input : Symbol(unknown) ->class : Symbol(unknown) ->type : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 19, 38)) +>type : Symbol(type, Decl(file.tsx, 19, 53)) >input : Symbol(unknown) : null } >label : Symbol(unknown) ->onDoubleClick : Symbol(unknown) +>onDoubleClick : Symbol(onDoubleClick, Decl(file.tsx, 22, 34)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >todo : Symbol(todo, Decl(file.tsx, 15, 42)) >todo : Symbol(todo, Decl(file.tsx, 15, 42)) @@ -102,8 +102,8 @@ let render = (ctrl, model) => >button : Symbol(unknown) ->class : Symbol(unknown) ->onClick : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 23, 35)) +>onClick : Symbol(onClick, Decl(file.tsx, 23, 51)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >ctrl : Symbol(ctrl, Decl(file.tsx, 6, 14)) >todo : Symbol(todo, Decl(file.tsx, 15, 42)) @@ -111,11 +111,11 @@ let render = (ctrl, model) =>
    >div : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 24, 32))
    >div : Symbol(unknown) ->class : Symbol(unknown) +>class : Symbol(class, Decl(file.tsx, 25, 36))
    >div : Symbol(unknown) diff --git a/tests/baselines/reference/tsxReactEmitNesting.types b/tests/baselines/reference/tsxReactEmitNesting.types index 7a1b3e82441e9..c456fd507bf21 100644 --- a/tests/baselines/reference/tsxReactEmitNesting.types +++ b/tests/baselines/reference/tsxReactEmitNesting.types @@ -19,12 +19,12 @@ let render = (ctrl, model) =>
    >

    todos <x>

      {model.filteredTodos.map((todo) =>
    • {(!todo.editable) ? : null }
    • )}
    : any >section : any ->class : any +>class : string
    >

    todos <x>

    : any >header : any ->class : any +>class : string

    todos <x>

    >

    todos <x>

    : any @@ -34,10 +34,10 @@ let render = (ctrl, model) => > : any >input : any ->class : any ->autofocus : any ->autocomplete : any ->placeholder : any +>class : string +>autofocus : true +>autocomplete : string +>placeholder : string >value : any >model.newTodo : any >model : any @@ -58,8 +58,8 @@ let render = (ctrl, model) =>
    >
      {model.filteredTodos.map((todo) =>
    • {(!todo.editable) ? : null }
    • )}
    : any >section : any ->class : any ->style : any +>class : string +>style : { display: string; } >{display:(model.todos && model.todos.length) ? "block" : "none"} : { display: string; } >display : string >(model.todos && model.todos.length) ? "block" : "none" : "block" | "none" @@ -79,8 +79,8 @@ let render = (ctrl, model) => > : any >input : any ->class : any ->type : any +>class : string +>type : string >onChange : any >ctrl.toggleAll.bind(ctrl) : any >ctrl.toggleAll.bind : any @@ -93,7 +93,7 @@ let render = (ctrl, model) =>
      >
        {model.filteredTodos.map((todo) =>
      • {(!todo.editable) ? : null }
      • )}
      : any >ul : any ->class : any +>class : string {model.filteredTodos.map((todo) => >model.filteredTodos.map((todo) =>
    • {(!todo.editable) ? : null }
    • ) : any @@ -108,7 +108,7 @@ let render = (ctrl, model) =>
    • >
    • {(!todo.editable) ? : null }
    • : any >li : any ->class : any +>class : { todo: boolean; completed: any; editing: boolean; } >{todo: true, completed: todo.completed, editing: todo == model.editedTodo} : { todo: boolean; completed: any; editing: boolean; } >todo : boolean >true : true @@ -126,7 +126,7 @@ let render = (ctrl, model) =>
      >
      {(!todo.editable) ? : null }
      : any >div : any ->class : any +>class : string {(!todo.editable) ? >(!todo.editable) ? : null : any @@ -139,8 +139,8 @@ let render = (ctrl, model) => > : any >input : any ->class : any ->type : any +>class : string +>type : string >input : any : null @@ -149,7 +149,7 @@ let render = (ctrl, model) => > : any >label : any ->onDoubleClick : any +>onDoubleClick : () => void >()=>{ctrl.editTodo(todo)} : () => void >ctrl.editTodo(todo) : any >ctrl.editTodo : any @@ -164,7 +164,7 @@ let render = (ctrl, model) => > : any >button : any ->class : any +>class : string >onClick : any >ctrl.removeTodo.bind(ctrl,todo) : any >ctrl.removeTodo.bind : any @@ -179,12 +179,12 @@ let render = (ctrl, model) =>
      >
      : any >div : any ->class : any +>class : string
      >
      : any >div : any ->class : any +>class : string
      >div : any diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.js b/tests/baselines/reference/tsxSpreadAttributesResolution1.js new file mode 100644 index 0000000000000..538bf316743d6 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.js @@ -0,0 +1,38 @@ +//// [file.tsx] + +import React = require('react'); + +class Poisoned extends React.Component<{}, {}> { + render() { + return
      Hello
      ; + } +} + +const obj: Object = {}; + +// OK +let p = ; +let y = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
      Hello
      ; + }; + return Poisoned; +}(React.Component)); +var obj = {}; +// OK +var p = ; +var y = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols new file mode 100644 index 0000000000000..d14e939ed7554 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +class Poisoned extends React.Component<{}, {}> { +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 1, 32)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) + + render() { +>render : Symbol(Poisoned.render, Decl(file.tsx, 3, 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)) + } +} + +const obj: Object = {}; +>obj : Symbol(obj, Decl(file.tsx, 9, 5)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 12, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 1, 32)) +>obj : Symbol(obj, Decl(file.tsx, 9, 5)) + +let y = ; +>y : Symbol(y, Decl(file.tsx, 13, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 1, 32)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.types b/tests/baselines/reference/tsxSpreadAttributesResolution1.types new file mode 100644 index 0000000000000..5b3182f63070d --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +class Poisoned extends React.Component<{}, {}> { +>Poisoned : Poisoned +>React.Component : React.Component<{}, {}> +>React : typeof React +>Component : typeof React.Component + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +const obj: Object = {}; +>obj : Object +>Object : Object +>{} : {} + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>obj : Object + +let y = ; +>y : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution10.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution10.errors.txt new file mode 100644 index 0000000000000..338e03a8e02bf --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution10.errors.txt @@ -0,0 +1,63 @@ +tests/cases/conformance/jsx/file.tsx(20,14): error TS2322: Type '{ x: 3; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. + Type '{ x: 3; }' is not assignable to type 'OptionProp'. + Types of property 'x' are incompatible. + Type '3' is not assignable to type '2'. +tests/cases/conformance/jsx/file.tsx(21,15): error TS2322: Type '{ x: "Hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. + Type '{ x: "Hi"; }' is not assignable to type 'OptionProp'. + Types of property 'x' are incompatible. + Type '"Hi"' is not assignable to type '2'. +tests/cases/conformance/jsx/file.tsx(22,15): error TS2322: Type '{ x: 3; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. + Type '{ x: 3; }' is not assignable to type 'OptionProp'. + Types of property 'x' are incompatible. + Type '3' is not assignable to type '2'. +tests/cases/conformance/jsx/file.tsx(23,15): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. + Type '{ x: true; }' is not assignable to type 'OptionProp'. + Types of property 'x' are incompatible. + Type 'true' is not assignable to type '2'. + + +==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== + + import React = require('react'); + + interface OptionProp { + x?: 2 + } + + class Opt extends React.Component { + render() { + return
      Hello
      ; + } + } + + const obj: OptionProp = {}; + const obj1: OptionProp = { + x: 2 + } + + // Error + let y = ; + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: 3; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: 3; }' is not assignable to type 'OptionProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. + let y1 = ; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: "Hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: "Hi"; }' is not assignable to type 'OptionProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '"Hi"' is not assignable to type '2'. + let y2 = ; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: 3; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: 3; }' is not assignable to type 'OptionProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. + let y3 = ; + ~ +!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & OptionProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: true; }' is not assignable to type 'OptionProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type '2'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution10.js b/tests/baselines/reference/tsxSpreadAttributesResolution10.js new file mode 100644 index 0000000000000..a460af219af8e --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution10.js @@ -0,0 +1,53 @@ +//// [file.tsx] + +import React = require('react'); + +interface OptionProp { + x?: 2 +} + +class Opt extends React.Component { + render() { + return
      Hello
      ; + } +} + +const obj: OptionProp = {}; +const obj1: OptionProp = { + x: 2 +} + +// Error +let y = ; +let y1 = ; +let y2 = ; +let y3 = ; + + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Opt = (function (_super) { + __extends(Opt, _super); + function Opt() { + return _super.apply(this, arguments) || this; + } + Opt.prototype.render = function () { + return
      Hello
      ; + }; + return Opt; +}(React.Component)); +var obj = {}; +var obj1 = { + x: 2 +}; +// Error +var y = ; +var y1 = ; +var y2 = ; +var y3 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution11.js b/tests/baselines/reference/tsxSpreadAttributesResolution11.js new file mode 100644 index 0000000000000..5d50ef9289eb7 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution11.js @@ -0,0 +1,68 @@ +//// [file.tsx] + +import React = require('react'); + +const obj = {}; +const obj1: { x: 2 } = { + x: 2 +} +const obj3: {y: true, overwrite: string } = { + y: true, + overwrite: "hi" +} + +interface Prop { + x: 2 + y: true + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
      Hello
      ; + } +} + +let anyobj: any; +// OK +let x = +let x1 = +let x2 = +let x3 = +let x4 = +let x5 = + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var obj = {}; +var obj1 = { + x: 2 +}; +var obj3 = { + y: true, + overwrite: "hi" +}; +var OverWriteAttr = (function (_super) { + __extends(OverWriteAttr, _super); + function OverWriteAttr() { + return _super.apply(this, arguments) || this; + } + OverWriteAttr.prototype.render = function () { + return
      Hello
      ; + }; + return OverWriteAttr; +}(React.Component)); +var anyobj; +// OK +var x = ; +var x1 = ; +var x2 = ; +var x3 = ; +var x4 = ; +var x5 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols new file mode 100644 index 0000000000000..c29ca5cd66259 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution11.symbols @@ -0,0 +1,104 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const obj = {}; +>obj : Symbol(obj, Decl(file.tsx, 3, 5)) + +const obj1: { x: 2 } = { +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) +>x : Symbol(x, Decl(file.tsx, 4, 13)) + + x: 2 +>x : Symbol(x, Decl(file.tsx, 4, 24)) +} +const obj3: {y: true, overwrite: string } = { +>obj3 : Symbol(obj3, Decl(file.tsx, 7, 5)) +>y : Symbol(y, Decl(file.tsx, 7, 13)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 7, 21)) + + y: true, +>y : Symbol(y, Decl(file.tsx, 7, 45)) + + overwrite: "hi" +>overwrite : Symbol(overwrite, Decl(file.tsx, 8, 12)) +} + +interface Prop { +>Prop : Symbol(Prop, Decl(file.tsx, 10, 1)) + + x: 2 +>x : Symbol(Prop.x, Decl(file.tsx, 12, 16)) + + y: true +>y : Symbol(Prop.y, Decl(file.tsx, 13, 8)) + + overwrite: string +>overwrite : Symbol(Prop.overwrite, Decl(file.tsx, 14, 11)) +} + +class OverWriteAttr extends React.Component { +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>Prop : Symbol(Prop, Decl(file.tsx, 10, 1)) + + render() { +>render : Symbol(OverWriteAttr.render, Decl(file.tsx, 18, 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)) + } +} + +let anyobj: any; +>anyobj : Symbol(anyobj, Decl(file.tsx, 24, 3)) + +// OK +let x = +>x : Symbol(x, Decl(file.tsx, 26, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>obj : Symbol(obj, Decl(file.tsx, 3, 5)) +>y : Symbol(y, Decl(file.tsx, 26, 31)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 26, 33)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) + +let x1 = +>x1 : Symbol(x1, Decl(file.tsx, 27, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) +>obj3 : Symbol(obj3, Decl(file.tsx, 7, 5)) + +let x2 = +>x2 : Symbol(x2, Decl(file.tsx, 28, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>x : Symbol(x, Decl(file.tsx, 28, 23)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 28, 29)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) +>y : Symbol(y, Decl(file.tsx, 28, 60)) + +let x3 = +>x3 : Symbol(x3, Decl(file.tsx, 29, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 29, 23)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) +>x : Symbol(x, Decl(file.tsx, 29, 48)) +>y : Symbol(y, Decl(file.tsx, 29, 60)) +>x : Symbol(x, Decl(file.tsx, 29, 68)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 29, 74)) + +let x4 = +>x4 : Symbol(x4, Decl(file.tsx, 30, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>x : Symbol(x, Decl(file.tsx, 30, 29)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 30, 41)) +>y : Symbol(y, Decl(file.tsx, 30, 67)) + +let x5 = +>x5 : Symbol(x5, Decl(file.tsx, 31, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>anyobj : Symbol(anyobj, Decl(file.tsx, 24, 3)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution11.types b/tests/baselines/reference/tsxSpreadAttributesResolution11.types new file mode 100644 index 0000000000000..30a123c4450e6 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution11.types @@ -0,0 +1,133 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +const obj = {}; +>obj : {} +>{} : {} + +const obj1: { x: 2 } = { +>obj1 : { x: 2; } +>x : 2 +>{ x: 2} : { x: 2; } + + x: 2 +>x : number +>2 : 2 +} +const obj3: {y: true, overwrite: string } = { +>obj3 : { y: true; overwrite: string; } +>y : true +>true : true +>overwrite : string +>{ y: true, overwrite: "hi"} : { y: true; overwrite: string; } + + y: true, +>y : boolean +>true : true + + overwrite: "hi" +>overwrite : string +>"hi" : "hi" +} + +interface Prop { +>Prop : Prop + + x: 2 +>x : 2 + + y: true +>y : true +>true : true + + overwrite: string +>overwrite : string +} + +class OverWriteAttr extends React.Component { +>OverWriteAttr : OverWriteAttr +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>Prop : Prop + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +let anyobj: any; +>anyobj : any + +// OK +let x = +>x : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>obj : {} +>y : true +>overwrite : string +>obj1 : { x: 2; } + +let x1 = +>x1 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>obj1 : { x: 2; } +>obj3 : { y: true; overwrite: string; } + +let x2 = +>x2 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>x : number +>3 : 3 +>overwrite : string +>obj1 : { x: 2; } +>{y: true} : { y: true; } +>y : boolean +>true : true + +let x3 = +>x3 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>overwrite : string +>obj1 : { x: 2; } +>x : number +>3 : 3 +>{y: true, x: 2, overwrite:"world"} : { y: true; x: 2; overwrite: string; } +>y : boolean +>true : true +>x : number +>2 : 2 +>overwrite : string +>"world" : "world" + +let x4 = +>x4 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>{x: 2} : { x: 2; } +>x : number +>2 : 2 +>{overwrite: "world"} : { overwrite: string; } +>overwrite : string +>"world" : "world" +>{y: true} : { y: true; } +>y : boolean +>true : true + +let x5 = +>x5 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>anyobj : any + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt new file mode 100644 index 0000000000000..f529c3b6fddab --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt @@ -0,0 +1,52 @@ +tests/cases/conformance/jsx/file.tsx(28,24): error TS2322: Type '{ x: 2; y: true; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. + Type '{ x: 2; y: true; overwrite: "hi"; }' is not assignable to type 'Prop'. + Types of property 'y' are incompatible. + Type 'true' is not assignable to type 'false'. +tests/cases/conformance/jsx/file.tsx(29,25): error TS2322: Type '{ y: true; x: 3; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. + Type '{ y: true; x: 3; overwrite: "hi"; }' is not assignable to type 'Prop'. + Types of property 'x' are incompatible. + Type '3' is not assignable to type '2'. + + +==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== + + import React = require('react'); + + const obj = {}; + const obj1: {x: 2} = { + x: 2 + } + const obj3: {y: false, overwrite: string} = { + y: false, + overwrite: "hi" + } + + interface Prop { + x: 2 + y: false + overwrite: string + } + + class OverWriteAttr extends React.Component { + render() { + return
      Hello
      ; + } + } + + let anyobj: any; + + // Error + let x = + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: 2; y: true; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: 2; y: true; overwrite: "hi"; }' is not assignable to type 'Prop'. +!!! error TS2322: Types of property 'y' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'false'. + let x1 = + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y: true; x: 3; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ y: true; x: 3; overwrite: "hi"; }' is not assignable to type 'Prop'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '3' is not assignable to type '2'. + let x2 = + \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution12.js b/tests/baselines/reference/tsxSpreadAttributesResolution12.js new file mode 100644 index 0000000000000..f7655003f40d4 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution12.js @@ -0,0 +1,64 @@ +//// [file.tsx] + +import React = require('react'); + +const obj = {}; +const obj1: {x: 2} = { + x: 2 +} +const obj3: {y: false, overwrite: string} = { + y: false, + overwrite: "hi" +} + +interface Prop { + x: 2 + y: false + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
      Hello
      ; + } +} + +let anyobj: any; + +// Error +let x = +let x1 = +let x2 = + + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var obj = {}; +var obj1 = { + x: 2 +}; +var obj3 = { + y: false, + overwrite: "hi" +}; +var OverWriteAttr = (function (_super) { + __extends(OverWriteAttr, _super); + function OverWriteAttr() { + return _super.apply(this, arguments) || this; + } + OverWriteAttr.prototype.render = function () { + return
      Hello
      ; + }; + return OverWriteAttr; +}(React.Component)); +var anyobj; +// Error +var x = ; +var x1 = ; +var x2 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt new file mode 100644 index 0000000000000..430b34b0087ca --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt @@ -0,0 +1,46 @@ +tests/cases/conformance/jsx/file.tsx(18,19): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{}' is not assignable to type 'PoisonedProp'. + Property 'x' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(19,9): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{}' is not assignable to type 'PoisonedProp'. + Property 'x' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ x: true; y: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{ x: true; y: true; }' is not assignable to type 'PoisonedProp'. + Types of property 'x' are incompatible. + Type 'true' is not assignable to type 'string'. + + +==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== + + import React = require('react'); + + interface PoisonedProp { + x: string; + y: "2"; + } + + class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } + } + + const obj = {}; + + // Error + let p = ; + ~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{}' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Property 'x' is missing in type '{}'. + let y = ; + ~~~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{}' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Property 'x' is missing in type '{}'. + let z = ; + ~~~ +!!! error TS2322: Type '{ x: true; y: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: true; y: true; }' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.js b/tests/baselines/reference/tsxSpreadAttributesResolution2.js new file mode 100644 index 0000000000000..98e475d59af4e --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.js @@ -0,0 +1,45 @@ +//// [file.tsx] + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: "2"; +} + +class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } +} + +const obj = {}; + +// Error +let p = ; +let y = ; +let z = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
      Hello
      ; + }; + return Poisoned; +}(React.Component)); +var obj = {}; +// Error +var p = ; +var y = ; +var z = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution3.js b/tests/baselines/reference/tsxSpreadAttributesResolution3.js new file mode 100644 index 0000000000000..18ccc054b2709 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution3.js @@ -0,0 +1,49 @@ +//// [file.tsx] + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: number; +} + +class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } +} + +const obj = { + x: "hello world", + y: 2 +}; + +// OK +let p = ; +let y = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
      Hello
      ; + }; + return Poisoned; +}(React.Component)); +var obj = { + x: "hello world", + y: 2 +}; +// OK +var p = ; +var y = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols new file mode 100644 index 0000000000000..7cf151f022bb4 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution3.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface PoisonedProp { +>PoisonedProp : Symbol(PoisonedProp, Decl(file.tsx, 1, 32)) + + x: string; +>x : Symbol(PoisonedProp.x, Decl(file.tsx, 3, 24)) + + y: number; +>y : Symbol(PoisonedProp.y, Decl(file.tsx, 4, 14)) +} + +class Poisoned extends React.Component { +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 6, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>PoisonedProp : Symbol(PoisonedProp, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(Poisoned.render, Decl(file.tsx, 8, 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)) + } +} + +const obj = { +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) + + x: "hello world", +>x : Symbol(x, Decl(file.tsx, 14, 13)) + + y: 2 +>y : Symbol(y, Decl(file.tsx, 15, 21)) + +}; + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 20, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 6, 1)) +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) + +let y = ; +>y : Symbol(y, Decl(file.tsx, 21, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 6, 1)) +>x : Symbol(x, Decl(file.tsx, 21, 17)) +>y : Symbol(y, Decl(file.tsx, 21, 24)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution3.types b/tests/baselines/reference/tsxSpreadAttributesResolution3.types new file mode 100644 index 0000000000000..4cf1fd49838a8 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution3.types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +interface PoisonedProp { +>PoisonedProp : PoisonedProp + + x: string; +>x : string + + y: number; +>y : number +} + +class Poisoned extends React.Component { +>Poisoned : Poisoned +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>PoisonedProp : PoisonedProp + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +const obj = { +>obj : { x: string; y: number; } +>{ x: "hello world", y: 2} : { x: string; y: number; } + + x: "hello world", +>x : string +>"hello world" : "hello world" + + y: 2 +>y : number +>2 : 2 + +}; + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>obj : { x: string; y: number; } + +let y = ; +>y : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>x : string +>y : number +>2 : 2 + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution4.js b/tests/baselines/reference/tsxSpreadAttributesResolution4.js new file mode 100644 index 0000000000000..e548e8863bf4e --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution4.js @@ -0,0 +1,47 @@ +//// [file.tsx] + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: 2; +} + +class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } +} + +const obj: PoisonedProp = { + x: "hello world", + y: 2 +}; + +// OK +let p = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
      Hello
      ; + }; + return Poisoned; +}(React.Component)); +var obj = { + x: "hello world", + y: 2 +}; +// OK +var p = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols new file mode 100644 index 0000000000000..a406de40bc1db --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution4.symbols @@ -0,0 +1,49 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface PoisonedProp { +>PoisonedProp : Symbol(PoisonedProp, Decl(file.tsx, 1, 32)) + + x: string; +>x : Symbol(PoisonedProp.x, Decl(file.tsx, 3, 24)) + + y: 2; +>y : Symbol(PoisonedProp.y, Decl(file.tsx, 4, 14)) +} + +class Poisoned extends React.Component { +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 6, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>PoisonedProp : Symbol(PoisonedProp, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(Poisoned.render, Decl(file.tsx, 8, 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)) + } +} + +const obj: PoisonedProp = { +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) +>PoisonedProp : Symbol(PoisonedProp, Decl(file.tsx, 1, 32)) + + x: "hello world", +>x : Symbol(x, Decl(file.tsx, 14, 27)) + + y: 2 +>y : Symbol(y, Decl(file.tsx, 15, 21)) + +}; + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 20, 3)) +>Poisoned : Symbol(Poisoned, Decl(file.tsx, 6, 1)) +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution4.types b/tests/baselines/reference/tsxSpreadAttributesResolution4.types new file mode 100644 index 0000000000000..be337e8139224 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution4.types @@ -0,0 +1,54 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +interface PoisonedProp { +>PoisonedProp : PoisonedProp + + x: string; +>x : string + + y: 2; +>y : 2 +} + +class Poisoned extends React.Component { +>Poisoned : Poisoned +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>PoisonedProp : PoisonedProp + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +const obj: PoisonedProp = { +>obj : PoisonedProp +>PoisonedProp : PoisonedProp +>{ x: "hello world", y: 2} : { x: string; y: 2; } + + x: "hello world", +>x : string +>"hello world" : "hello world" + + y: 2 +>y : number +>2 : 2 + +}; + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Poisoned : typeof Poisoned +>obj : PoisonedProp + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt new file mode 100644 index 0000000000000..9b575313e5fa2 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt @@ -0,0 +1,33 @@ +tests/cases/conformance/jsx/file.tsx(21,19): error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{ x: string; y: number; }' is not assignable to type 'PoisonedProp'. + Types of property 'y' are incompatible. + Type 'number' is not assignable to type '2'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + + import React = require('react'); + + interface PoisonedProp { + x: string; + y: 2; + } + + class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } + } + + let obj = { + x: "hello world", + y: 2 + }; + + // Error as "obj" has type { x: string; y: number } + let p = ; + ~~~~~~~~ +!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: string; y: number; }' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Types of property 'y' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type '2'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution5.js b/tests/baselines/reference/tsxSpreadAttributesResolution5.js new file mode 100644 index 0000000000000..8208b2d9dc7cb --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution5.js @@ -0,0 +1,47 @@ +//// [file.tsx] + +import React = require('react'); + +interface PoisonedProp { + x: string; + y: 2; +} + +class Poisoned extends React.Component { + render() { + return
      Hello
      ; + } +} + +let obj = { + x: "hello world", + y: 2 +}; + +// Error as "obj" has type { x: string; y: number } +let p = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Poisoned = (function (_super) { + __extends(Poisoned, _super); + function Poisoned() { + return _super.apply(this, arguments) || this; + } + Poisoned.prototype.render = function () { + return
      Hello
      ; + }; + return Poisoned; +}(React.Component)); +var obj = { + x: "hello world", + y: 2 +}; +// Error as "obj" has type { x: string; y: number } +var p = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt new file mode 100644 index 0000000000000..c3bd7484fbfcc --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution6.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/jsx/file.tsx(14,10): error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + + import React = require('react'); + + type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + + class TextComponent extends React.Component { + render() { + return Some Text..; + } + } + + // Error + let x = + ~~~~~~~~~~~~~ +!!! error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. + + const textProps: TextProps = { + editable: false + }; \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution6.js b/tests/baselines/reference/tsxSpreadAttributesResolution6.js new file mode 100644 index 0000000000000..0b4e50793db9f --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution6.js @@ -0,0 +1,43 @@ +//// [file.tsx] + +import React = require('react'); + +type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + +class TextComponent extends React.Component { + render() { + return Some Text..; + } +} + +// Error +let x = + +const textProps: TextProps = { + editable: false +}; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var TextComponent = (function (_super) { + __extends(TextComponent, _super); + function TextComponent() { + return _super.apply(this, arguments) || this; + } + TextComponent.prototype.render = function () { + return Some Text..; + }; + return TextComponent; +}(React.Component)); +// Error +var x = ; +var textProps = { + editable: false +}; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution7.errors.txt new file mode 100644 index 0000000000000..c71459c4a381c --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.errors.txt @@ -0,0 +1,34 @@ +tests/cases/conformance/jsx/file.tsx(18,11): error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. +tests/cases/conformance/jsx/file.tsx(25,11): error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. + + +==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== + + import React = require('react'); + + type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + + class TextComponent extends React.Component { + render() { + return Some Text..; + } + } + + // OK + const textPropsFalse: TextProps = { + editable: false + }; + + let y1 = + ~~~~~~~~~~~~~ +!!! error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. + + const textPropsTrue: TextProps = { + editable: true, + onEdit: () => {} + }; + + let y2 = + ~~~~~~~~~~~~~ +!!! error TS2600: JSX element attributes type '({ editable: false; } & { children?: ReactNode; }) | ({ editable: true; onEdit: (newText: string) => void; } & { children?: ReactNode; })' may not be a union type. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.js b/tests/baselines/reference/tsxSpreadAttributesResolution7.js new file mode 100644 index 0000000000000..47ee5ef15ed8b --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.js @@ -0,0 +1,55 @@ +//// [file.tsx] + +import React = require('react'); + +type TextProps = { editable: false } + | { editable: true, onEdit: (newText: string) => void }; + +class TextComponent extends React.Component { + render() { + return Some Text..; + } +} + +// OK +const textPropsFalse: TextProps = { + editable: false +}; + +let y1 = + +const textPropsTrue: TextProps = { + editable: true, + onEdit: () => {} +}; + +let y2 = + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var TextComponent = (function (_super) { + __extends(TextComponent, _super); + function TextComponent() { + return _super.apply(this, arguments) || this; + } + TextComponent.prototype.render = function () { + return Some Text..; + }; + return TextComponent; +}(React.Component)); +// OK +var textPropsFalse = { + editable: false +}; +var y1 = ; +var textPropsTrue = { + editable: true, + onEdit: function () { } +}; +var y2 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols new file mode 100644 index 0000000000000..f40b79ae6166d --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +type TextProps = { editable: false } +>TextProps : Symbol(TextProps, Decl(file.tsx, 1, 32)) +>editable : Symbol(editable, Decl(file.tsx, 3, 18)) + + | { editable: true, onEdit: (newText: string) => void }; +>editable : Symbol(editable, Decl(file.tsx, 4, 18)) +>onEdit : Symbol(onEdit, Decl(file.tsx, 4, 34)) +>newText : Symbol(newText, Decl(file.tsx, 4, 44)) + +class TextComponent extends React.Component { +>TextComponent : Symbol(TextComponent, Decl(file.tsx, 4, 71)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>TextProps : Symbol(TextProps, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(TextComponent.render, Decl(file.tsx, 6, 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)) + } +} + +// OK +const textPropsFalse: TextProps = { +>textPropsFalse : Symbol(textPropsFalse, Decl(file.tsx, 13, 5)) +>TextProps : Symbol(TextProps, Decl(file.tsx, 1, 32)) + + editable: false +>editable : Symbol(editable, Decl(file.tsx, 13, 35)) + +}; + +let y1 = +>y1 : Symbol(y1, Decl(file.tsx, 17, 3)) +>TextComponent : Symbol(TextComponent, Decl(file.tsx, 4, 71)) +>textPropsFalse : Symbol(textPropsFalse, Decl(file.tsx, 13, 5)) + +const textPropsTrue: TextProps = { +>textPropsTrue : Symbol(textPropsTrue, Decl(file.tsx, 19, 5)) +>TextProps : Symbol(TextProps, Decl(file.tsx, 1, 32)) + + editable: true, +>editable : Symbol(editable, Decl(file.tsx, 19, 34)) + + onEdit: () => {} +>onEdit : Symbol(onEdit, Decl(file.tsx, 20, 19)) + +}; + +let y2 = +>y2 : Symbol(y2, Decl(file.tsx, 24, 3)) +>TextComponent : Symbol(TextComponent, Decl(file.tsx, 4, 71)) +>textPropsTrue : Symbol(textPropsTrue, Decl(file.tsx, 19, 5)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution7.types b/tests/baselines/reference/tsxSpreadAttributesResolution7.types new file mode 100644 index 0000000000000..db423de090486 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution7.types @@ -0,0 +1,72 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +type TextProps = { editable: false } +>TextProps : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } +>editable : false +>false : false + + | { editable: true, onEdit: (newText: string) => void }; +>editable : true +>true : true +>onEdit : (newText: string) => void +>newText : string + +class TextComponent extends React.Component { +>TextComponent : TextComponent +>React.Component : React.Component<{ editable: false; } | { editable: true; onEdit: (newText: string) => void; }, {}> +>React : typeof React +>Component : typeof React.Component +>TextProps : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } + + render() { +>render : () => JSX.Element + + return Some Text..; +>Some Text.. : JSX.Element +>span : any +>span : any + } +} + +// OK +const textPropsFalse: TextProps = { +>textPropsFalse : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } +>TextProps : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } +>{ editable: false} : { editable: false; } + + editable: false +>editable : boolean +>false : false + +}; + +let y1 = +>y1 : JSX.Element +> : JSX.Element +>TextComponent : typeof TextComponent +>textPropsFalse : { editable: false; } + +const textPropsTrue: TextProps = { +>textPropsTrue : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } +>TextProps : { editable: false; } | { editable: true; onEdit: (newText: string) => void; } +>{ editable: true, onEdit: () => {}} : { editable: true; onEdit: () => void; } + + editable: true, +>editable : boolean +>true : true + + onEdit: () => {} +>onEdit : () => void +>() => {} : () => void + +}; + +let y2 = +>y2 : JSX.Element +> : JSX.Element +>TextComponent : typeof TextComponent +>textPropsTrue : { editable: true; onEdit: (newText: string) => void; } + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution8.js b/tests/baselines/reference/tsxSpreadAttributesResolution8.js new file mode 100644 index 0000000000000..188c89fb21dd5 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution8.js @@ -0,0 +1,58 @@ +//// [file.tsx] + +import React = require('react'); + +const obj = {}; +const obj1 = { + x: 2 +} +const obj3 = { + y: true, + overwrite: "hi" +} + +interface Prop { + x: number + y: boolean + overwrite: string +} + +class OverWriteAttr extends React.Component { + render() { + return
      Hello
      ; + } +} + +// OK +let x = +let x1 = + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var obj = {}; +var obj1 = { + x: 2 +}; +var obj3 = { + y: true, + overwrite: "hi" +}; +var OverWriteAttr = (function (_super) { + __extends(OverWriteAttr, _super); + function OverWriteAttr() { + return _super.apply(this, arguments) || this; + } + OverWriteAttr.prototype.render = function () { + return
      Hello
      ; + }; + return OverWriteAttr; +}(React.Component)); +// OK +var x = ; +var x1 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols new file mode 100644 index 0000000000000..6a9f9c05fce2d --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution8.symbols @@ -0,0 +1,68 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +const obj = {}; +>obj : Symbol(obj, Decl(file.tsx, 3, 5)) + +const obj1 = { +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) + + x: 2 +>x : Symbol(x, Decl(file.tsx, 4, 14)) +} +const obj3 = { +>obj3 : Symbol(obj3, Decl(file.tsx, 7, 5)) + + y: true, +>y : Symbol(y, Decl(file.tsx, 7, 14)) + + overwrite: "hi" +>overwrite : Symbol(overwrite, Decl(file.tsx, 8, 12)) +} + +interface Prop { +>Prop : Symbol(Prop, Decl(file.tsx, 10, 1)) + + x: number +>x : Symbol(Prop.x, Decl(file.tsx, 12, 16)) + + y: boolean +>y : Symbol(Prop.y, Decl(file.tsx, 13, 13)) + + overwrite: string +>overwrite : Symbol(Prop.overwrite, Decl(file.tsx, 14, 14)) +} + +class OverWriteAttr extends React.Component { +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>Prop : Symbol(Prop, Decl(file.tsx, 10, 1)) + + render() { +>render : Symbol(OverWriteAttr.render, Decl(file.tsx, 18, 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)) + } +} + +// OK +let x = +>x : Symbol(x, Decl(file.tsx, 25, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>obj : Symbol(obj, Decl(file.tsx, 3, 5)) +>y : Symbol(y, Decl(file.tsx, 25, 31)) +>overwrite : Symbol(overwrite, Decl(file.tsx, 25, 33)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) + +let x1 = +>x1 : Symbol(x1, Decl(file.tsx, 26, 3)) +>OverWriteAttr : Symbol(OverWriteAttr, Decl(file.tsx, 16, 1)) +>obj1 : Symbol(obj1, Decl(file.tsx, 4, 5)) +>obj3 : Symbol(obj3, Decl(file.tsx, 7, 5)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution8.types b/tests/baselines/reference/tsxSpreadAttributesResolution8.types new file mode 100644 index 0000000000000..dcf13976a0e4e --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution8.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +const obj = {}; +>obj : {} +>{} : {} + +const obj1 = { +>obj1 : { x: number; } +>{ x: 2} : { x: number; } + + x: 2 +>x : number +>2 : 2 +} +const obj3 = { +>obj3 : { y: boolean; overwrite: string; } +>{ y: true, overwrite: "hi"} : { y: boolean; overwrite: string; } + + y: true, +>y : boolean +>true : true + + overwrite: "hi" +>overwrite : string +>"hi" : "hi" +} + +interface Prop { +>Prop : Prop + + x: number +>x : number + + y: boolean +>y : boolean + + overwrite: string +>overwrite : string +} + +class OverWriteAttr extends React.Component { +>OverWriteAttr : OverWriteAttr +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>Prop : Prop + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +// OK +let x = +>x : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>obj : {} +>y : true +>overwrite : string +>obj1 : { x: number; } + +let x1 = +>x1 : JSX.Element +> : JSX.Element +>OverWriteAttr : typeof OverWriteAttr +>obj1 : { x: number; } +>obj3 : { y: boolean; overwrite: string; } + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution9.js b/tests/baselines/reference/tsxSpreadAttributesResolution9.js new file mode 100644 index 0000000000000..1ef5d08175355 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution9.js @@ -0,0 +1,55 @@ +//// [file.tsx] + +import React = require('react'); + +interface OptionProp { + x?: 2 + y?: boolean +} + +class Opt extends React.Component { + render() { + return
      Hello
      ; + } +} + +const obj: OptionProp = {}; +const obj1: OptionProp = { + x: 2 +} + +// OK +let p = ; +let y = ; +let y1 = ; +let y2 = ; +let y3 = ; + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var React = require("react"); +var Opt = (function (_super) { + __extends(Opt, _super); + function Opt() { + return _super.apply(this, arguments) || this; + } + Opt.prototype.render = function () { + return
      Hello
      ; + }; + return Opt; +}(React.Component)); +var obj = {}; +var obj1 = { + x: 2 +}; +// OK +var p = ; +var y = ; +var y1 = ; +var y2 = ; +var y3 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols new file mode 100644 index 0000000000000..e58e92cd29a65 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution9.symbols @@ -0,0 +1,69 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface OptionProp { +>OptionProp : Symbol(OptionProp, Decl(file.tsx, 1, 32)) + + x?: 2 +>x : Symbol(OptionProp.x, Decl(file.tsx, 3, 22)) + + y?: boolean +>y : Symbol(OptionProp.y, Decl(file.tsx, 4, 9)) +} + +class Opt extends React.Component { +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>OptionProp : Symbol(OptionProp, Decl(file.tsx, 1, 32)) + + render() { +>render : Symbol(Opt.render, Decl(file.tsx, 8, 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)) + } +} + +const obj: OptionProp = {}; +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) +>OptionProp : Symbol(OptionProp, Decl(file.tsx, 1, 32)) + +const obj1: OptionProp = { +>obj1 : Symbol(obj1, Decl(file.tsx, 15, 5)) +>OptionProp : Symbol(OptionProp, Decl(file.tsx, 1, 32)) + + x: 2 +>x : Symbol(x, Decl(file.tsx, 15, 26)) +} + +// OK +let p = ; +>p : Symbol(p, Decl(file.tsx, 20, 3)) +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) + +let y = ; +>y : Symbol(y, Decl(file.tsx, 21, 3)) +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) +>obj : Symbol(obj, Decl(file.tsx, 14, 5)) + +let y1 = ; +>y1 : Symbol(y1, Decl(file.tsx, 22, 3)) +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) +>obj1 : Symbol(obj1, Decl(file.tsx, 15, 5)) + +let y2 = ; +>y2 : Symbol(y2, Decl(file.tsx, 23, 3)) +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) +>obj1 : Symbol(obj1, Decl(file.tsx, 15, 5)) +>y : Symbol(y, Decl(file.tsx, 23, 23)) + +let y3 = ; +>y3 : Symbol(y3, Decl(file.tsx, 24, 3)) +>Opt : Symbol(Opt, Decl(file.tsx, 6, 1)) +>x : Symbol(x, Decl(file.tsx, 24, 13)) + diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution9.types b/tests/baselines/reference/tsxSpreadAttributesResolution9.types new file mode 100644 index 0000000000000..ccc84af648841 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution9.types @@ -0,0 +1,79 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react'); +>React : typeof React + +interface OptionProp { +>OptionProp : OptionProp + + x?: 2 +>x : 2 + + y?: boolean +>y : boolean +} + +class Opt extends React.Component { +>Opt : Opt +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>OptionProp : OptionProp + + render() { +>render : () => JSX.Element + + return
      Hello
      ; +>
      Hello
      : JSX.Element +>div : any +>div : any + } +} + +const obj: OptionProp = {}; +>obj : OptionProp +>OptionProp : OptionProp +>{} : {} + +const obj1: OptionProp = { +>obj1 : OptionProp +>OptionProp : OptionProp +>{ x: 2} : { x: 2; } + + x: 2 +>x : number +>2 : 2 +} + +// OK +let p = ; +>p : JSX.Element +> : JSX.Element +>Opt : typeof Opt + +let y = ; +>y : JSX.Element +> : JSX.Element +>Opt : typeof Opt +>obj : OptionProp + +let y1 = ; +>y1 : JSX.Element +> : JSX.Element +>Opt : typeof Opt +>obj1 : OptionProp + +let y2 = ; +>y2 : JSX.Element +> : JSX.Element +>Opt : typeof Opt +>obj1 : OptionProp +>y : true + +let y3 = ; +>y3 : JSX.Element +> : JSX.Element +>Opt : typeof Opt +>x : number +>2 : 2 + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.js new file mode 100644 index 0000000000000..4b3d582f6ccf5 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.js @@ -0,0 +1,64 @@ +//// [file.tsx] + +import React = require('react') + +declare function OneThing(k: {yxx: string}): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string, yy2: boolean}): JSX.Element; +declare function OneThing(l1: {data: string, "data-prop": boolean}): JSX.Element; + +// OK +const c1 = +const c2 = +const c3 = +const c4 = + +declare function TestingOneThing({y1: string}): JSX.Element; +declare function TestingOneThing(j: {"extra-data": string, yy?: string}): JSX.Element; +declare function TestingOneThing(n: {yy: number, direction?: number}): JSX.Element; +declare function TestingOneThing(n: {yy: string, name: string}): JSX.Element; + +// OK +const d1 = ; +const d2 = ; +const d3 = ; +const d4 = ; +const d5 = ; + + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; + +// OK +const e1 = +const e2 = +const e3 = +const e4 = +const e5 = +const e6 = + + + + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + // OK + var c1 = ; + var c2 = ; + var c3 = ; + var c4 = ; + // OK + var d1 = ; + var d2 = ; + var d3 = ; + var d4 = ; + var d5 = ; + // OK + var e1 = ; + var e2 = ; + var e3 = ; + var e4 = ; + var e5 = ; + var e6 = ; +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.symbols new file mode 100644 index 0000000000000..cc559031caae3 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.symbols @@ -0,0 +1,176 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +declare function OneThing(k: {yxx: string}): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>k : Symbol(k, Decl(file.tsx, 3, 26)) +>yxx : Symbol(yxx, Decl(file.tsx, 3, 30)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>l : Symbol(l, Decl(file.tsx, 4, 26)) +>yy : Symbol(yy, Decl(file.tsx, 4, 30)) +>yy1 : Symbol(yy1, Decl(file.tsx, 4, 41)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OneThing(l: {yy: number, yy1: string, yy2: boolean}): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>l : Symbol(l, Decl(file.tsx, 5, 26)) +>yy : Symbol(yy, Decl(file.tsx, 5, 30)) +>yy1 : Symbol(yy1, Decl(file.tsx, 5, 41)) +>yy2 : Symbol(yy2, Decl(file.tsx, 5, 54)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OneThing(l1: {data: string, "data-prop": boolean}): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>l1 : Symbol(l1, Decl(file.tsx, 6, 26)) +>data : Symbol(data, Decl(file.tsx, 6, 31)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +const c1 = +>c1 : Symbol(c1, Decl(file.tsx, 9, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>yxx : Symbol(yxx, Decl(file.tsx, 9, 20)) + +const c2 = +>c2 : Symbol(c2, Decl(file.tsx, 10, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>yy : Symbol(yy, Decl(file.tsx, 10, 20)) +>yy1 : Symbol(yy1, Decl(file.tsx, 10, 29)) + +const c3 = +>c3 : Symbol(c3, Decl(file.tsx, 11, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>yxx : Symbol(yxx, Decl(file.tsx, 11, 20)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 11, 32)) + +const c4 = +>c4 : Symbol(c4, Decl(file.tsx, 12, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 57), Decl(file.tsx, 4, 69), Decl(file.tsx, 5, 83)) +>data : Symbol(data, Decl(file.tsx, 12, 20)) +>data-prop : Symbol(data-prop, Decl(file.tsx, 12, 33)) + +declare function TestingOneThing({y1: string}): JSX.Element; +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>y1 : Symbol(y1) +>string : Symbol(string, Decl(file.tsx, 14, 34)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function TestingOneThing(j: {"extra-data": string, yy?: string}): JSX.Element; +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>j : Symbol(j, Decl(file.tsx, 15, 33)) +>yy : Symbol(yy, Decl(file.tsx, 15, 58)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function TestingOneThing(n: {yy: number, direction?: number}): JSX.Element; +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>n : Symbol(n, Decl(file.tsx, 16, 33)) +>yy : Symbol(yy, Decl(file.tsx, 16, 37)) +>direction : Symbol(direction, Decl(file.tsx, 16, 48)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function TestingOneThing(n: {yy: string, name: string}): JSX.Element; +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>n : Symbol(n, Decl(file.tsx, 17, 33)) +>yy : Symbol(yy, Decl(file.tsx, 17, 37)) +>name : Symbol(name, Decl(file.tsx, 17, 48)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +const d1 = ; +>d1 : Symbol(d1, Decl(file.tsx, 20, 5)) +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>y1 : Symbol(y1, Decl(file.tsx, 20, 27)) +>extra-data : Symbol(extra-data, Decl(file.tsx, 20, 30)) + +const d2 = ; +>d2 : Symbol(d2, Decl(file.tsx, 21, 5)) +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>extra-data : Symbol(extra-data, Decl(file.tsx, 21, 27)) + +const d3 = ; +>d3 : Symbol(d3, Decl(file.tsx, 22, 5)) +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>extra-data : Symbol(extra-data, Decl(file.tsx, 22, 27)) +>yy : Symbol(yy, Decl(file.tsx, 22, 46)) + +const d4 = ; +>d4 : Symbol(d4, Decl(file.tsx, 23, 5)) +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>extra-data : Symbol(extra-data, Decl(file.tsx, 23, 27)) +>yy : Symbol(yy, Decl(file.tsx, 23, 46)) +>direction : Symbol(direction, Decl(file.tsx, 23, 53)) + +const d5 = ; +>d5 : Symbol(d5, Decl(file.tsx, 24, 5)) +>TestingOneThing : Symbol(TestingOneThing, Decl(file.tsx, 12, 46), Decl(file.tsx, 14, 60), Decl(file.tsx, 15, 86), Decl(file.tsx, 16, 83)) +>extra-data : Symbol(extra-data, Decl(file.tsx, 24, 27)) +>yy : Symbol(yy, Decl(file.tsx, 24, 46)) +>name : Symbol(name, Decl(file.tsx, 24, 57)) + + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>a : Symbol(a, Decl(file.tsx, 27, 33)) +>y1 : Symbol(y1, Decl(file.tsx, 27, 37)) +>y2 : Symbol(y2, Decl(file.tsx, 27, 49)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>a : Symbol(a, Decl(file.tsx, 28, 33)) +>y1 : Symbol(y1, Decl(file.tsx, 28, 37)) +>y2 : Symbol(y2, Decl(file.tsx, 28, 49)) +>y3 : Symbol(y3, Decl(file.tsx, 28, 62)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +const e1 = +>e1 : Symbol(e1, Decl(file.tsx, 31, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) + +const e2 = +>e2 : Symbol(e2, Decl(file.tsx, 32, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>extra-prop : Symbol(extra-prop, Decl(file.tsx, 32, 27)) + +const e3 = +>e3 : Symbol(e3, Decl(file.tsx, 33, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>y1 : Symbol(y1, Decl(file.tsx, 33, 27)) + +const e4 = +>e4 : Symbol(e4, Decl(file.tsx, 34, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>y1 : Symbol(y1, Decl(file.tsx, 34, 27)) +>y2 : Symbol(y2, Decl(file.tsx, 34, 38)) + +const e5 = +>e5 : Symbol(e5, Decl(file.tsx, 35, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>y1 : Symbol(y1, Decl(file.tsx, 35, 27)) +>y3 : Symbol(y3, Decl(file.tsx, 35, 30)) + +const e6 = +>e6 : Symbol(e6, Decl(file.tsx, 36, 5)) +>TestingOptional : Symbol(TestingOptional, Decl(file.tsx, 24, 72), Decl(file.tsx, 27, 77)) +>y1 : Symbol(y1, Decl(file.tsx, 36, 27)) +>y3 : Symbol(y3, Decl(file.tsx, 36, 30)) +>y2 : Symbol(y2, Decl(file.tsx, 36, 33)) + + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.types new file mode 100644 index 0000000000000..a37ac8072301e --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload1.types @@ -0,0 +1,196 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : typeof React + +declare function OneThing(k: {yxx: string}): JSX.Element; +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>k : { yxx: string; } +>yxx : string +>JSX : any +>Element : JSX.Element + +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>l : { yy: number; yy1: string; } +>yy : number +>yy1 : string +>JSX : any +>Element : JSX.Element + +declare function OneThing(l: {yy: number, yy1: string, yy2: boolean}): JSX.Element; +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>l : { yy: number; yy1: string; yy2: boolean; } +>yy : number +>yy1 : string +>yy2 : boolean +>JSX : any +>Element : JSX.Element + +declare function OneThing(l1: {data: string, "data-prop": boolean}): JSX.Element; +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>l1 : { data: string; "data-prop": boolean; } +>data : string +>JSX : any +>Element : JSX.Element + +// OK +const c1 = +>c1 : JSX.Element +> : JSX.Element +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>yxx : string + +const c2 = +>c2 : JSX.Element +> : JSX.Element +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>yy : number +>100 : 100 +>yy1 : string + +const c3 = +>c3 : JSX.Element +> : JSX.Element +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>yxx : string +>ignore-prop : true + +const c4 = +>c4 : JSX.Element +> : JSX.Element +>OneThing : { (k: { yxx: string; }): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; (l: { yy: number; yy1: string; yy2: boolean; }): JSX.Element; (l1: { data: string; "data-prop": boolean; }): JSX.Element; } +>data : string +>data-prop : true + +declare function TestingOneThing({y1: string}): JSX.Element; +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>y1 : any +>string : any +>JSX : any +>Element : JSX.Element + +declare function TestingOneThing(j: {"extra-data": string, yy?: string}): JSX.Element; +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>j : { "extra-data": string; yy?: string; } +>yy : string +>JSX : any +>Element : JSX.Element + +declare function TestingOneThing(n: {yy: number, direction?: number}): JSX.Element; +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>n : { yy: number; direction?: number; } +>yy : number +>direction : number +>JSX : any +>Element : JSX.Element + +declare function TestingOneThing(n: {yy: string, name: string}): JSX.Element; +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>n : { yy: string; name: string; } +>yy : string +>name : string +>JSX : any +>Element : JSX.Element + +// OK +const d1 = ; +>d1 : JSX.Element +> : JSX.Element +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>y1 : true +>extra-data : true + +const d2 = ; +>d2 : JSX.Element +> : JSX.Element +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>extra-data : string + +const d3 = ; +>d3 : JSX.Element +> : JSX.Element +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>extra-data : string +>yy : string + +const d4 = ; +>d4 : JSX.Element +> : JSX.Element +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>extra-data : string +>yy : number +>9 : 9 +>direction : number +>10 : 10 + +const d5 = ; +>d5 : JSX.Element +> : JSX.Element +>TestingOneThing : { ({y1: string}: { y1: any; }): JSX.Element; (j: { "extra-data": string; yy?: string; }): JSX.Element; (n: { yy: number; direction?: number; }): JSX.Element; (n: { yy: string; name: string; }): JSX.Element; } +>extra-data : string +>yy : string +>name : string + + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>a : { y1?: string; y2?: number; } +>y1 : string +>y2 : number +>JSX : any +>Element : JSX.Element + +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>a : { y1: boolean; y2?: number; y3: boolean; } +>y1 : boolean +>y2 : number +>y3 : boolean +>JSX : any +>Element : JSX.Element + +// OK +const e1 = +>e1 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } + +const e2 = +>e2 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>extra-prop : true + +const e3 = +>e3 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>y1 : string + +const e4 = +>e4 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>y1 : string +>y2 : number +>1000 : 1000 + +const e5 = +>e5 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>y1 : true +>y3 : true + +const e6 = +>e6 : JSX.Element +> : JSX.Element +>TestingOptional : { (a: { y1?: string; y2?: number; }): JSX.Element; (a: { y1: boolean; y2?: number; y3: boolean; }): JSX.Element; } +>y1 : true +>y3 : true +>y2 : number +>10 : 10 + + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js new file mode 100644 index 0000000000000..b34b8ff3b5015 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js @@ -0,0 +1,62 @@ +//// [file.tsx] + +import React = require('react') +declare function OneThing(): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; + +let obj = { + yy: 10, + yy1: "hello" +} + +let obj1 = { + yy: true +} + +let obj2 = { + yy: 500, + "ignore-prop": "hello" +} + +let defaultObj = undefined; + +// OK +const c1 = +const c2 = +const c3 = +const c4 = +const c5 = +const c6 = +const c7 = ; // No error. should pick second overload +const c8 = +const c9 = ; +const c10 = ; + + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + var obj = { + yy: 10, + yy1: "hello" + }; + var obj1 = { + yy: true + }; + var obj2 = { + yy: 500, + "ignore-prop": "hello" + }; + var defaultObj = undefined; + // OK + var c1 = ; + var c2 = ; + var c3 = ; + var c4 = ; + var c5 = ; + var c6 = ; + var c7 = ; // No error. should pick second overload + var c8 = ; + var c9 = ; + var c10 = ; +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols new file mode 100644 index 0000000000000..6a9b975897282 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols @@ -0,0 +1,104 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +declare function OneThing(): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>l : Symbol(l, Decl(file.tsx, 3, 26)) +>yy : Symbol(yy, Decl(file.tsx, 3, 30)) +>yy1 : Symbol(yy1, Decl(file.tsx, 3, 41)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +let obj = { +>obj : Symbol(obj, Decl(file.tsx, 5, 3)) + + yy: 10, +>yy : Symbol(yy, Decl(file.tsx, 5, 11)) + + yy1: "hello" +>yy1 : Symbol(yy1, Decl(file.tsx, 6, 11)) +} + +let obj1 = { +>obj1 : Symbol(obj1, Decl(file.tsx, 10, 3)) + + yy: true +>yy : Symbol(yy, Decl(file.tsx, 10, 12)) +} + +let obj2 = { +>obj2 : Symbol(obj2, Decl(file.tsx, 14, 3)) + + yy: 500, +>yy : Symbol(yy, Decl(file.tsx, 14, 12)) + + "ignore-prop": "hello" +} + +let defaultObj = undefined; +>defaultObj : Symbol(defaultObj, Decl(file.tsx, 19, 3)) +>undefined : Symbol(undefined) + +// OK +const c1 = +>c1 : Symbol(c1, Decl(file.tsx, 22, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) + +const c2 = +>c2 : Symbol(c2, Decl(file.tsx, 23, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>obj : Symbol(obj, Decl(file.tsx, 5, 3)) + +const c3 = +>c3 : Symbol(c3, Decl(file.tsx, 24, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) + +const c4 = +>c4 : Symbol(c4, Decl(file.tsx, 25, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>obj1 : Symbol(obj1, Decl(file.tsx, 10, 3)) +>obj : Symbol(obj, Decl(file.tsx, 5, 3)) + +const c5 = +>c5 : Symbol(c5, Decl(file.tsx, 26, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>obj1 : Symbol(obj1, Decl(file.tsx, 10, 3)) +>yy : Symbol(yy, Decl(file.tsx, 26, 30)) +>yy1 : Symbol(yy1, Decl(file.tsx, 26, 44)) + +const c6 = +>c6 : Symbol(c6, Decl(file.tsx, 27, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>obj1 : Symbol(obj1, Decl(file.tsx, 10, 3)) +>yy : Symbol(yy, Decl(file.tsx, 27, 36)) +>yy1 : Symbol(yy1, Decl(file.tsx, 27, 46)) + +const c7 = ; // No error. should pick second overload +>c7 : Symbol(c7, Decl(file.tsx, 28, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>defaultObj : Symbol(defaultObj, Decl(file.tsx, 19, 3)) +>yy : Symbol(yy, Decl(file.tsx, 28, 36)) +>obj : Symbol(obj, Decl(file.tsx, 5, 3)) + +const c8 = +>c8 : Symbol(c8, Decl(file.tsx, 29, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 29, 20)) + +const c9 = ; +>c9 : Symbol(c9, Decl(file.tsx, 30, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) + +const c10 = ; +>c10 : Symbol(c10, Decl(file.tsx, 31, 5)) +>OneThing : Symbol(OneThing, Decl(file.tsx, 1, 31), Decl(file.tsx, 2, 41)) +>obj2 : Symbol(obj2, Decl(file.tsx, 14, 3)) +>yy1 : Symbol(yy1, Decl(file.tsx, 31, 31)) + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types new file mode 100644 index 0000000000000..3736f3b999199 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types @@ -0,0 +1,132 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : typeof React + +declare function OneThing(): JSX.Element; +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>JSX : any +>Element : JSX.Element + +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>l : { yy: number; yy1: string; } +>yy : number +>yy1 : string +>JSX : any +>Element : JSX.Element + +let obj = { +>obj : { yy: number; yy1: string; } +>{ yy: 10, yy1: "hello"} : { yy: number; yy1: string; } + + yy: 10, +>yy : number +>10 : 10 + + yy1: "hello" +>yy1 : string +>"hello" : "hello" +} + +let obj1 = { +>obj1 : { yy: boolean; } +>{ yy: true} : { yy: boolean; } + + yy: true +>yy : boolean +>true : true +} + +let obj2 = { +>obj2 : { yy: number; "ignore-prop": string; } +>{ yy: 500, "ignore-prop": "hello"} : { yy: number; "ignore-prop": string; } + + yy: 500, +>yy : number +>500 : 500 + + "ignore-prop": "hello" +>"hello" : "hello" +} + +let defaultObj = undefined; +>defaultObj : any +>undefined : undefined + +// OK +const c1 = +>c1 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } + +const c2 = +>c2 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>obj : { yy: number; yy1: string; } + +const c3 = +>c3 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>{} : {} + +const c4 = +>c4 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>obj1 : { yy: boolean; } +>obj : { yy: number; yy1: string; } + +const c5 = +>c5 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>obj1 : { yy: boolean; } +>yy : number +>42 : 42 +>{yy1: "hi"} : { yy1: string; } +>yy1 : string +>"hi" : "hi" + +const c6 = +>c6 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>obj1 : { yy: boolean; } +>{yy: 10000, yy1: "true"} : { yy: number; yy1: string; } +>yy : number +>10000 : 10000 +>yy1 : string +>"true" : "true" + +const c7 = ; // No error. should pick second overload +>c7 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>defaultObj : undefined +>yy : true +>obj : { yy: number; yy1: string; } + +const c8 = +>c8 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>ignore-prop : number +>100 : 100 + +const c9 = ; +>c9 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>{ "ignore-prop":200 } : { "ignore-prop": number; } +>200 : 200 + +const c10 = ; +>c10 : JSX.Element +> : JSX.Element +>OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } +>obj2 : { yy: number; "ignore-prop": string; } +>yy1 : string + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js new file mode 100644 index 0000000000000..4a810834e0b8d --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js @@ -0,0 +1,38 @@ +//// [file.tsx] + +interface Context { + color: any; +} +declare function ZeroThingOrTwoThing(): JSX.Element; +declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; + +let obj2 = undefined; + +// OK +const two1 = ; +const two2 = ; +const two3 = ; // it is just any so we allow it to pass through +const two4 = ; // it is just any so we allow it to pass through +const two5 = ; // it is just any so we allow it to pass through + +declare function ThreeThing(l: {y1: string}): JSX.Element; +declare function ThreeThing(l: {y2: string}): JSX.Element; +declare function ThreeThing(l: {yy: number, yy1: string}, context: Context, updater: any): JSX.Element; + +// OK +const three1 = ; +const three2 = ; +const three3 = ; // it is just any so we allow it to pass through + +//// [file.jsx] +var obj2 = undefined; +// OK +var two1 = ; +var two2 = ; +var two3 = ; // it is just any so we allow it to pass through +var two4 = ; // it is just any so we allow it to pass through +var two5 = ; // it is just any so we allow it to pass through +// OK +var three1 = ; +var three2 = ; +var three3 = ; // it is just any so we allow it to pass through diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols new file mode 100644 index 0000000000000..de5aaa25972d5 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols @@ -0,0 +1,98 @@ +=== tests/cases/conformance/jsx/file.tsx === + +interface Context { +>Context : Symbol(Context, Decl(file.tsx, 0, 0)) + + color: any; +>color : Symbol(Context.color, Decl(file.tsx, 1, 19)) +} +declare function ZeroThingOrTwoThing(): JSX.Element; +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>l : Symbol(l, Decl(file.tsx, 5, 37)) +>yy : Symbol(yy, Decl(file.tsx, 5, 41)) +>yy1 : Symbol(yy1, Decl(file.tsx, 5, 52)) +>context : Symbol(context, Decl(file.tsx, 5, 66)) +>Context : Symbol(Context, Decl(file.tsx, 0, 0)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +let obj2 = undefined; +>obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) +>undefined : Symbol(undefined) + +// OK +const two1 = ; +>two1 : Symbol(two1, Decl(file.tsx, 10, 5)) +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) + +const two2 = ; +>two2 : Symbol(two2, Decl(file.tsx, 11, 5)) +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>yy : Symbol(yy, Decl(file.tsx, 11, 33)) +>yy1 : Symbol(yy1, Decl(file.tsx, 11, 42)) + +const two3 = ; // it is just any so we allow it to pass through +>two3 : Symbol(two3, Decl(file.tsx, 12, 5)) +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) + +const two4 = ; // it is just any so we allow it to pass through +>two4 : Symbol(two4, Decl(file.tsx, 13, 5)) +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>yy : Symbol(yy, Decl(file.tsx, 13, 33)) +>obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) + +const two5 = ; // it is just any so we allow it to pass through +>two5 : Symbol(two5, Decl(file.tsx, 14, 5)) +>ZeroThingOrTwoThing : Symbol(ZeroThingOrTwoThing, Decl(file.tsx, 3, 1), Decl(file.tsx, 4, 52)) +>obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) +>yy : Symbol(yy, Decl(file.tsx, 14, 44)) + +declare function ThreeThing(l: {y1: string}): JSX.Element; +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>l : Symbol(l, Decl(file.tsx, 16, 28)) +>y1 : Symbol(y1, Decl(file.tsx, 16, 32)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function ThreeThing(l: {y2: string}): JSX.Element; +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>l : Symbol(l, Decl(file.tsx, 17, 28)) +>y2 : Symbol(y2, Decl(file.tsx, 17, 32)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function ThreeThing(l: {yy: number, yy1: string}, context: Context, updater: any): JSX.Element; +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>l : Symbol(l, Decl(file.tsx, 18, 28)) +>yy : Symbol(yy, Decl(file.tsx, 18, 32)) +>yy1 : Symbol(yy1, Decl(file.tsx, 18, 43)) +>context : Symbol(context, Decl(file.tsx, 18, 57)) +>Context : Symbol(Context, Decl(file.tsx, 0, 0)) +>updater : Symbol(updater, Decl(file.tsx, 18, 75)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +const three1 = ; +>three1 : Symbol(three1, Decl(file.tsx, 21, 5)) +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>yy : Symbol(yy, Decl(file.tsx, 21, 26)) +>yy1 : Symbol(yy1, Decl(file.tsx, 21, 34)) + +const three2 = ; +>three2 : Symbol(three2, Decl(file.tsx, 22, 5)) +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>y2 : Symbol(y2, Decl(file.tsx, 22, 26)) + +const three3 = ; // it is just any so we allow it to pass through +>three3 : Symbol(three3, Decl(file.tsx, 23, 5)) +>ThreeThing : Symbol(ThreeThing, Decl(file.tsx, 14, 58), Decl(file.tsx, 16, 58), Decl(file.tsx, 17, 58)) +>obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) +>y2 : Symbol(y2, Decl(file.tsx, 23, 36)) + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types new file mode 100644 index 0000000000000..ce3e5e7abb6b2 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types @@ -0,0 +1,111 @@ +=== tests/cases/conformance/jsx/file.tsx === + +interface Context { +>Context : Context + + color: any; +>color : any +} +declare function ZeroThingOrTwoThing(): JSX.Element; +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>JSX : any +>Element : JSX.Element + +declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>l : { yy: number; yy1: string; } +>yy : number +>yy1 : string +>context : Context +>Context : Context +>JSX : any +>Element : JSX.Element + +let obj2 = undefined; +>obj2 : any +>undefined : undefined + +// OK +const two1 = ; +>two1 : JSX.Element +> : JSX.Element +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } + +const two2 = ; +>two2 : JSX.Element +> : JSX.Element +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>yy : number +>100 : 100 +>yy1 : string + +const two3 = ; // it is just any so we allow it to pass through +>two3 : JSX.Element +> : JSX.Element +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>obj2 : undefined + +const two4 = ; // it is just any so we allow it to pass through +>two4 : JSX.Element +> : JSX.Element +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>yy : number +>1000 : 1000 +>obj2 : undefined + +const two5 = ; // it is just any so we allow it to pass through +>two5 : JSX.Element +> : JSX.Element +>ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } +>obj2 : undefined +>yy : number +>1000 : 1000 + +declare function ThreeThing(l: {y1: string}): JSX.Element; +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>l : { y1: string; } +>y1 : string +>JSX : any +>Element : JSX.Element + +declare function ThreeThing(l: {y2: string}): JSX.Element; +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>l : { y2: string; } +>y2 : string +>JSX : any +>Element : JSX.Element + +declare function ThreeThing(l: {yy: number, yy1: string}, context: Context, updater: any): JSX.Element; +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>l : { yy: number; yy1: string; } +>yy : number +>yy1 : string +>context : Context +>Context : Context +>updater : any +>JSX : any +>Element : JSX.Element + +// OK +const three1 = ; +>three1 : JSX.Element +> : JSX.Element +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>yy : number +>99 : 99 +>yy1 : string + +const three2 = ; +>three2 : JSX.Element +> : JSX.Element +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>y2 : string + +const three3 = ; // it is just any so we allow it to pass through +>three3 : JSX.Element +> : JSX.Element +>ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } +>obj2 : undefined +>y2 : number +>10 : 10 + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt new file mode 100644 index 0000000000000..f43bd414ef8ff --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt @@ -0,0 +1,112 @@ +tests/cases/conformance/jsx/file.tsx(13,22): error TS2322: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +tests/cases/conformance/jsx/file.tsx(14,22): error TS2322: Type '{ yy: 10; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Type '{ yy: 10; }' is not assignable to type '{ yy: number; yy1: string; }'. + Property 'yy1' is missing in type '{ yy: 10; }'. +tests/cases/conformance/jsx/file.tsx(15,22): error TS2322: Type '{ yy1: true; yy: number; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Type '{ yy1: true; yy: number; }' is not assignable to type '{ yy: number; yy1: string; }'. + Types of property 'yy1' are incompatible. + Type 'true' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(16,22): error TS2322: Type '{ extra: string; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Property 'extra' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +tests/cases/conformance/jsx/file.tsx(17,22): error TS2322: Type '{ y1: 10000; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +tests/cases/conformance/jsx/file.tsx(18,22): error TS2322: Type '{ yy: boolean; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Type '{ yy: boolean; yy1: string; }' is not assignable to type '{ yy: number; yy1: string; }'. + Types of property 'yy' are incompatible. + Type 'boolean' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(26,29): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { yy: string; direction?: number; }'. + Type '{}' is not assignable to type '{ yy: string; direction?: number; }'. + Property 'yy' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(27,29): error TS2322: Type '{ yy: "hello"; direction: "left"; }' is not assignable to type 'IntrinsicAttributes & { yy: string; direction?: number; }'. + Type '{ yy: "hello"; direction: "left"; }' is not assignable to type '{ yy: string; direction?: number; }'. + Types of property 'direction' are incompatible. + Type '"left"' is not assignable to type 'number'. +tests/cases/conformance/jsx/file.tsx(33,29): error TS2322: Type '{ y1: true; y3: "hello"; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. + Type '{ y1: true; y3: "hello"; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. + Types of property 'y3' are incompatible. + Type '"hello"' is not assignable to type 'boolean'. +tests/cases/conformance/jsx/file.tsx(34,29): error TS2322: Type '{ y1: "hello"; y2: 1000; y3: true; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. + Type '{ y1: "hello"; y2: 1000; y3: true; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. + Types of property 'y1' are incompatible. + Type '"hello"' is not assignable to type 'boolean'. + + +==== tests/cases/conformance/jsx/file.tsx (10 errors) ==== + + import React = require('react') + declare function OneThing(): JSX.Element; + declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; + + let obj = { + yy: 10, + yy1: "hello" + } + let obj2 = undefined; + + // Error + const c0 = ; // extra property; + ~~~~~~~~~ +!!! error TS2322: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + const c1 = ; // missing property; + ~~~~~~~ +!!! error TS2322: Type '{ yy: 10; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Type '{ yy: 10; }' is not assignable to type '{ yy: number; yy1: string; }'. +!!! error TS2322: Property 'yy1' is missing in type '{ yy: 10; }'. + const c2 = ; // type incompatible; + ~~~~~~~~~~~~ +!!! error TS2322: Type '{ yy1: true; yy: number; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Type '{ yy1: true; yy: number; }' is not assignable to type '{ yy: number; yy1: string; }'. +!!! error TS2322: Types of property 'yy1' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'string'. + const c3 = ; // Extra attribute; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ extra: string; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + const c4 = ; // extra property; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y1: 10000; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + const c5 = ; // type incompatible; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ yy: boolean; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Type '{ yy: boolean; yy1: string; }' is not assignable to type '{ yy: number; yy1: string; }'. +!!! error TS2322: Types of property 'yy' are incompatible. +!!! error TS2322: Type 'boolean' is not assignable to type 'number'. + const c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + const c7 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + + declare function TestingOneThing(j: {"extra-data": string}): JSX.Element; + declare function TestingOneThing(n: {yy: string, direction?: number}): JSX.Element; + + // Error + const d1 = + ~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { yy: string; direction?: number; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ yy: string; direction?: number; }'. +!!! error TS2322: Property 'yy' is missing in type '{}'. + const d2 = + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ yy: "hello"; direction: "left"; }' is not assignable to type 'IntrinsicAttributes & { yy: string; direction?: number; }'. +!!! error TS2322: Type '{ yy: "hello"; direction: "left"; }' is not assignable to type '{ yy: string; direction?: number; }'. +!!! error TS2322: Types of property 'direction' are incompatible. +!!! error TS2322: Type '"left"' is not assignable to type 'number'. + + declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; + declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; + + // Error + const e1 = + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y1: true; y3: "hello"; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Type '{ y1: true; y3: "hello"; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Types of property 'y3' are incompatible. +!!! error TS2322: Type '"hello"' is not assignable to type 'boolean'. + const e2 = + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y1: "hello"; y2: 1000; y3: true; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Type '{ y1: "hello"; y2: 1000; y3: true; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Types of property 'y1' are incompatible. +!!! error TS2322: Type '"hello"' is not assignable to type 'boolean'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js new file mode 100644 index 0000000000000..f43b4a845d01e --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js @@ -0,0 +1,61 @@ +//// [file.tsx] + +import React = require('react') +declare function OneThing(): JSX.Element; +declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; + +let obj = { + yy: 10, + yy1: "hello" +} +let obj2 = undefined; + +// Error +const c0 = ; // extra property; +const c1 = ; // missing property; +const c2 = ; // type incompatible; +const c3 = ; // Extra attribute; +const c4 = ; // extra property; +const c5 = ; // type incompatible; +const c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not +const c7 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + +declare function TestingOneThing(j: {"extra-data": string}): JSX.Element; +declare function TestingOneThing(n: {yy: string, direction?: number}): JSX.Element; + +// Error +const d1 = +const d2 = + +declare function TestingOptional(a: {y1?: string, y2?: number}): JSX.Element; +declare function TestingOptional(a: {y1: boolean, y2?: number, y3: boolean}): JSX.Element; + +// Error +const e1 = +const e2 = + + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + var obj = { + yy: 10, + yy1: "hello" + }; + var obj2 = undefined; + // Error + var c0 = ; // extra property; + var c1 = ; // missing property; + var c2 = ; // type incompatible; + var c3 = ; // Extra attribute; + var c4 = ; // extra property; + var c5 = ; // type incompatible; + var c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + var c7 = ; // Should error as there is extra attribute that doesn't match any. Current it is not + // Error + var d1 = ; + var d2 = ; + // Error + var e1 = ; + var e2 = ; +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt new file mode 100644 index 0000000000000..b3d954baa841a --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -0,0 +1,110 @@ +tests/cases/conformance/jsx/file.tsx(49,24): error TS2322: Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +tests/cases/conformance/jsx/file.tsx(50,24): error TS2322: Type '{ to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +tests/cases/conformance/jsx/file.tsx(51,24): error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +tests/cases/conformance/jsx/file.tsx(52,24): error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +tests/cases/conformance/jsx/file.tsx(54,24): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Type '{}' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(55,24): error TS2322: Type '{ children: 10; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Type '{ children: 10; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ children: 10; }'. +tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type '{ children: "hello"; className: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Type '{ children: "hello"; className: true; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ children: "hello"; className: true; }'. +tests/cases/conformance/jsx/file.tsx(57,24): error TS2322: Type '{ data-format: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Type '{ data-format: true; }' is not assignable to type 'HyphenProps'. + Types of property '"data-format"' are incompatible. + Type 'true' is not assignable to type 'string'. + + +==== tests/cases/conformance/jsx/file.tsx (8 errors) ==== + + import React = require('react') + + export interface ClickableProps { + children?: string; + className?: string; + } + + export interface ButtonProps extends ClickableProps { + onClick: React.MouseEventHandler; + } + + export interface LinkProps extends ClickableProps { + to: string; + } + + export interface HyphenProps extends ClickableProps { + "data-format": string; + } + + let obj0 = { + to: "world" + }; + + let obj1 = { + children: "hi", + to: "boo" + } + + let obj2 = { + onClick: ()=>{} + } + + let obj3 = undefined; + + export function MainButton(buttonProps: ButtonProps): JSX.Element; + export function MainButton(linkProps: LinkProps): JSX.Element; + export function MainButton(hyphenProps: HyphenProps): JSX.Element; + export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.to) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); + } + + // Error + const b0 = {}}>GO; // extra property; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + const b1 = {}} {...obj0}>Hello world; // extra property; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + const b2 = ; // extra property + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + const b3 = {}}} />; // extra property + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + const b4 = ; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed + const b5 = ; // Spread doesn't retain method declaration + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{}' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{}'. + const b6 = ; // incorrect type for optional attribute + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ children: 10; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ children: 10; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ children: 10; }'. + const b7 = ; // incorrect type for optional attribute + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ children: "hello"; className: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ children: "hello"; className: true; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ children: "hello"; className: true; }'. + const b8 = ; // incorrect type for specified hyphanted name + ~~~~~~~~~~~ +!!! error TS2322: Type '{ data-format: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ data-format: true; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Types of property '"data-format"' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js new file mode 100644 index 0000000000000..21cae8eb39541 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js @@ -0,0 +1,92 @@ +//// [file.tsx] + +import React = require('react') + +export interface ClickableProps { + children?: string; + className?: string; +} + +export interface ButtonProps extends ClickableProps { + onClick: React.MouseEventHandler; +} + +export interface LinkProps extends ClickableProps { + to: string; +} + +export interface HyphenProps extends ClickableProps { + "data-format": string; +} + +let obj0 = { + to: "world" +}; + +let obj1 = { + children: "hi", + to: "boo" +} + +let obj2 = { + onClick: ()=>{} +} + +let obj3 = undefined; + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +export function MainButton(linkProps: LinkProps): JSX.Element; +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.to) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); +} + +// Error +const b0 = {}}>GO; // extra property; +const b1 = {}} {...obj0}>Hello world; // extra property; +const b2 = ; // extra property +const b3 = {}}} />; // extra property +const b4 = ; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed +const b5 = ; // Spread doesn't retain method declaration +const b6 = ; // incorrect type for optional attribute +const b7 = ; // incorrect type for optional attribute +const b8 = ; // incorrect type for specified hyphanted name + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + var obj0 = { + to: "world" + }; + var obj1 = { + children: "hi", + to: "boo" + }; + var obj2 = { + onClick: function () { } + }; + var obj3 = undefined; + function MainButton(props) { + var linkProps = props; + if (linkProps.to) { + return this._buildMainLink(props); + } + return this._buildMainButton(props); + } + exports.MainButton = MainButton; + // Error + var b0 = GO; // extra property; + var b1 = Hello world; // extra property; + var b2 = ; // extra property + var b3 = ; // extra property + var b4 = ; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed + var b5 = ; // Spread doesn't retain method declaration + var b6 = ; // incorrect type for optional attribute + var b7 = ; // incorrect type for optional attribute + var b8 = ; // incorrect type for specified hyphanted name +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js new file mode 100644 index 0000000000000..071a7d0534788 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js @@ -0,0 +1,94 @@ +//// [file.tsx] + +import React = require('react') + +export interface ClickableProps { + children?: string; + className?: string; +} + +export interface ButtonProps extends ClickableProps { + onClick: React.MouseEventHandler; +} + +export interface LinkProps extends ClickableProps { + to: string; +} + +export interface HyphenProps extends ClickableProps { + "data-format": string; +} + +let obj = { + children: "hi", + to: "boo" +} +let obj1 = undefined; +let obj2 = { + onClick: () => {} +} + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +export function MainButton(linkProps: LinkProps): JSX.Element; +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { + const linkProps = props as LinkProps; + if(linkProps.to) { + return this._buildMainLink(props); + } + + return this._buildMainButton(props); +} + +// OK +const b0 = GO; +const b1 = {}}>Hello world; +const b2 = ; +const b3 = ; +const b4 = ; // any; just pick the first overload +const b5 = ; // should pick the second overload +const b6 = ; +const b7 = { console.log("hi") }}} />; +const b8 = ; // OK; method declaration get discarded +const b9 = GO; +const b10 = GO; +const b11 = {}} className="hello" data-format>Hello world; +const b12 = + + + + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + var obj = { + children: "hi", + to: "boo" + }; + var obj1 = undefined; + var obj2 = { + onClick: function () { } + }; + function MainButton(props) { + var linkProps = props; + if (linkProps.to) { + return this._buildMainLink(props); + } + return this._buildMainButton(props); + } + exports.MainButton = MainButton; + // OK + var b0 = GO; + var b1 = Hello world; + var b2 = ; + var b3 = ; + var b4 = ; // any; just pick the first overload + var b5 = ; // should pick the second overload + var b6 = ; + var b7 = ; + var b8 = ; // OK; method declaration get discarded + var b9 = GO; + var b10 = GO; + var b11 = Hello world; + var b12 = ; +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols new file mode 100644 index 0000000000000..308752e1c217a --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols @@ -0,0 +1,193 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +export interface ClickableProps { +>ClickableProps : Symbol(ClickableProps, Decl(file.tsx, 1, 31)) + + children?: string; +>children : Symbol(ClickableProps.children, Decl(file.tsx, 3, 33)) + + className?: string; +>className : Symbol(ClickableProps.className, Decl(file.tsx, 4, 22)) +} + +export interface ButtonProps extends ClickableProps { +>ButtonProps : Symbol(ButtonProps, Decl(file.tsx, 6, 1)) +>ClickableProps : Symbol(ClickableProps, Decl(file.tsx, 1, 31)) + + onClick: React.MouseEventHandler; +>onClick : Symbol(ButtonProps.onClick, Decl(file.tsx, 8, 53)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>MouseEventHandler : Symbol(React.MouseEventHandler, Decl(react.d.ts, 388, 66)) +} + +export interface LinkProps extends ClickableProps { +>LinkProps : Symbol(LinkProps, Decl(file.tsx, 10, 1)) +>ClickableProps : Symbol(ClickableProps, Decl(file.tsx, 1, 31)) + + to: string; +>to : Symbol(LinkProps.to, Decl(file.tsx, 12, 51)) +} + +export interface HyphenProps extends ClickableProps { +>HyphenProps : Symbol(HyphenProps, Decl(file.tsx, 14, 1)) +>ClickableProps : Symbol(ClickableProps, Decl(file.tsx, 1, 31)) + + "data-format": string; +} + +let obj = { +>obj : Symbol(obj, Decl(file.tsx, 20, 3)) + + children: "hi", +>children : Symbol(children, Decl(file.tsx, 20, 11)) + + to: "boo" +>to : Symbol(to, Decl(file.tsx, 21, 19)) +} +let obj1 = undefined; +>obj1 : Symbol(obj1, Decl(file.tsx, 24, 3)) +>undefined : Symbol(undefined) + +let obj2 = { +>obj2 : Symbol(obj2, Decl(file.tsx, 25, 3)) + + onClick: () => {} +>onClick : Symbol(onClick, Decl(file.tsx, 25, 12)) +} + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>buttonProps : Symbol(buttonProps, Decl(file.tsx, 29, 27)) +>ButtonProps : Symbol(ButtonProps, Decl(file.tsx, 6, 1)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +export function MainButton(linkProps: LinkProps): JSX.Element; +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>linkProps : Symbol(linkProps, Decl(file.tsx, 30, 27)) +>LinkProps : Symbol(LinkProps, Decl(file.tsx, 10, 1)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>hyphenProps : Symbol(hyphenProps, Decl(file.tsx, 31, 27)) +>HyphenProps : Symbol(HyphenProps, Decl(file.tsx, 14, 1)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>props : Symbol(props, Decl(file.tsx, 32, 27)) +>ButtonProps : Symbol(ButtonProps, Decl(file.tsx, 6, 1)) +>LinkProps : Symbol(LinkProps, Decl(file.tsx, 10, 1)) +>HyphenProps : Symbol(HyphenProps, Decl(file.tsx, 14, 1)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + + const linkProps = props as LinkProps; +>linkProps : Symbol(linkProps, Decl(file.tsx, 33, 9)) +>props : Symbol(props, Decl(file.tsx, 32, 27)) +>LinkProps : Symbol(LinkProps, Decl(file.tsx, 10, 1)) + + if(linkProps.to) { +>linkProps.to : Symbol(LinkProps.to, Decl(file.tsx, 12, 51)) +>linkProps : Symbol(linkProps, Decl(file.tsx, 33, 9)) +>to : Symbol(LinkProps.to, Decl(file.tsx, 12, 51)) + + return this._buildMainLink(props); +>props : Symbol(props, Decl(file.tsx, 32, 27)) + } + + return this._buildMainButton(props); +>props : Symbol(props, Decl(file.tsx, 32, 27)) +} + +// OK +const b0 = GO; +>b0 : Symbol(b0, Decl(file.tsx, 42, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>to : Symbol(to, Decl(file.tsx, 42, 22)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) + +const b1 = {}}>Hello world; +>b1 : Symbol(b1, Decl(file.tsx, 43, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>onClick : Symbol(onClick, Decl(file.tsx, 43, 22)) +>e : Symbol(e, Decl(file.tsx, 43, 33)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) + +const b2 = ; +>b2 : Symbol(b2, Decl(file.tsx, 44, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>obj : Symbol(obj, Decl(file.tsx, 20, 3)) + +const b3 = ; +>b3 : Symbol(b3, Decl(file.tsx, 45, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>to : Symbol(to, Decl(file.tsx, 45, 28)) +>obj : Symbol(obj, Decl(file.tsx, 20, 3)) + +const b4 = ; // any; just pick the first overload +>b4 : Symbol(b4, Decl(file.tsx, 46, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>obj1 : Symbol(obj1, Decl(file.tsx, 24, 3)) + +const b5 = ; // should pick the second overload +>b5 : Symbol(b5, Decl(file.tsx, 47, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>obj1 : Symbol(obj1, Decl(file.tsx, 24, 3)) +>to : Symbol(to, Decl(file.tsx, 47, 32)) + +const b6 = ; +>b6 : Symbol(b6, Decl(file.tsx, 48, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>obj2 : Symbol(obj2, Decl(file.tsx, 25, 3)) + +const b7 = { console.log("hi") }}} />; +>b7 : Symbol(b7, Decl(file.tsx, 49, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>onClick : Symbol(onClick, Decl(file.tsx, 49, 28)) +>console.log : Symbol(Console.log, Decl(lib.d.ts, --, --)) +>console : Symbol(console, Decl(lib.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.d.ts, --, --)) + +const b8 = ; // OK; method declaration get discarded +>b8 : Symbol(b8, Decl(file.tsx, 50, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>obj : Symbol(obj, Decl(file.tsx, 20, 3)) +>onClick : Symbol(onClick, Decl(file.tsx, 50, 37)) + +const b9 = GO; +>b9 : Symbol(b9, Decl(file.tsx, 51, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>to : Symbol(to, Decl(file.tsx, 51, 22)) +>extra-prop : Symbol(extra-prop, Decl(file.tsx, 51, 38)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) + +const b10 = GO; +>b10 : Symbol(b10, Decl(file.tsx, 52, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>to : Symbol(to, Decl(file.tsx, 52, 23)) +>children : Symbol(children, Decl(file.tsx, 52, 39)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) + +const b11 = {}} className="hello" data-format>Hello world; +>b11 : Symbol(b11, Decl(file.tsx, 53, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>onClick : Symbol(onClick, Decl(file.tsx, 53, 23)) +>e : Symbol(e, Decl(file.tsx, 53, 34)) +>className : Symbol(className, Decl(file.tsx, 53, 43)) +>data-format : Symbol(data-format, Decl(file.tsx, 53, 61)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) + +const b12 = +>b12 : Symbol(b12, Decl(file.tsx, 54, 5)) +>MainButton : Symbol(MainButton, Decl(file.tsx, 27, 1), Decl(file.tsx, 29, 66), Decl(file.tsx, 30, 62), Decl(file.tsx, 31, 66)) +>data-format : Symbol(data-format, Decl(file.tsx, 54, 23)) + + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types new file mode 100644 index 0000000000000..296619e2051b6 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types @@ -0,0 +1,229 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : typeof React + +export interface ClickableProps { +>ClickableProps : ClickableProps + + children?: string; +>children : string + + className?: string; +>className : string +} + +export interface ButtonProps extends ClickableProps { +>ButtonProps : ButtonProps +>ClickableProps : ClickableProps + + onClick: React.MouseEventHandler; +>onClick : React.EventHandler> +>React : any +>MouseEventHandler : React.EventHandler> +} + +export interface LinkProps extends ClickableProps { +>LinkProps : LinkProps +>ClickableProps : ClickableProps + + to: string; +>to : string +} + +export interface HyphenProps extends ClickableProps { +>HyphenProps : HyphenProps +>ClickableProps : ClickableProps + + "data-format": string; +} + +let obj = { +>obj : { children: string; to: string; } +>{ children: "hi", to: "boo"} : { children: string; to: string; } + + children: "hi", +>children : string +>"hi" : "hi" + + to: "boo" +>to : string +>"boo" : "boo" +} +let obj1 = undefined; +>obj1 : any +>undefined : undefined + +let obj2 = { +>obj2 : { onClick: () => void; } +>{ onClick: () => {}} : { onClick: () => void; } + + onClick: () => {} +>onClick : () => void +>() => {} : () => void +} + +export function MainButton(buttonProps: ButtonProps): JSX.Element; +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>buttonProps : ButtonProps +>ButtonProps : ButtonProps +>JSX : any +>Element : JSX.Element + +export function MainButton(linkProps: LinkProps): JSX.Element; +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>linkProps : LinkProps +>LinkProps : LinkProps +>JSX : any +>Element : JSX.Element + +export function MainButton(hyphenProps: HyphenProps): JSX.Element; +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>hyphenProps : HyphenProps +>HyphenProps : HyphenProps +>JSX : any +>Element : JSX.Element + +export function MainButton(props: ButtonProps | LinkProps | HyphenProps): JSX.Element { +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>props : ButtonProps | LinkProps | HyphenProps +>ButtonProps : ButtonProps +>LinkProps : LinkProps +>HyphenProps : HyphenProps +>JSX : any +>Element : JSX.Element + + const linkProps = props as LinkProps; +>linkProps : LinkProps +>props as LinkProps : LinkProps +>props : ButtonProps | LinkProps | HyphenProps +>LinkProps : LinkProps + + if(linkProps.to) { +>linkProps.to : string +>linkProps : LinkProps +>to : string + + return this._buildMainLink(props); +>this._buildMainLink(props) : any +>this._buildMainLink : any +>this : any +>_buildMainLink : any +>props : ButtonProps | LinkProps | HyphenProps + } + + return this._buildMainButton(props); +>this._buildMainButton(props) : any +>this._buildMainButton : any +>this : any +>_buildMainButton : any +>props : ButtonProps | LinkProps | HyphenProps +} + +// OK +const b0 = GO; +>b0 : JSX.Element +>GO : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>to : string +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } + +const b1 = {}}>Hello world; +>b1 : JSX.Element +> {}}>Hello world : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>onClick : (e: React.MouseEvent) => void +>(e) => {} : (e: React.MouseEvent) => void +>e : React.MouseEvent +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } + +const b2 = ; +>b2 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>obj : { children: string; to: string; } + +const b3 = ; +>b3 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>{to: 10000} : { to: number; } +>to : number +>10000 : 10000 +>obj : { children: string; to: string; } + +const b4 = ; // any; just pick the first overload +>b4 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>obj1 : undefined + +const b5 = ; // should pick the second overload +>b5 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>obj1 : undefined +>to : string + +const b6 = ; +>b6 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>obj2 : { onClick: () => void; } + +const b7 = { console.log("hi") }}} />; +>b7 : JSX.Element +> { console.log("hi") }}} /> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>{onClick: () => { console.log("hi") }} : { onClick: () => void; } +>onClick : () => void +>() => { console.log("hi") } : () => void +>console.log("hi") : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>"hi" : "hi" + +const b8 = ; // OK; method declaration get discarded +>b8 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>obj : { children: string; to: string; } +>{onClick() {}} : { onClick(): void; } +>onClick : () => void + +const b9 = GO; +>b9 : JSX.Element +>GO : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>to : string +>extra-prop : true +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } + +const b10 = GO; +>b10 : JSX.Element +>GO : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>to : string +>children : string +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } + +const b11 = {}} className="hello" data-format>Hello world; +>b11 : JSX.Element +> {}} className="hello" data-format>Hello world : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>onClick : (e: React.MouseEvent) => void +>(e) => {} : (e: React.MouseEvent) => void +>e : React.MouseEvent +>className : string +>data-format : true +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } + +const b12 = +>b12 : JSX.Element +> : JSX.Element +>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } +>data-format : string + + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt index e1f7570d9c0a0..4b95ae8a38fb3 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -1,7 +1,14 @@ -tests/cases/conformance/jsx/file.tsx(12,9): error TS2324: Property 'name' is missing in type 'IntrinsicAttributes & { name: string; }'. -tests/cases/conformance/jsx/file.tsx(12,16): error TS2339: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. -tests/cases/conformance/jsx/file.tsx(19,15): error TS2322: Type '42' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(21,15): error TS2339: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(16,16): error TS2322: Type '{ naaame: "world"; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. + Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. +tests/cases/conformance/jsx/file.tsx(24,15): error TS2322: Type '{ name: 42; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. + Type '{ name: 42; }' is not assignable to type '{ name?: string; }'. + Types of property 'name' are incompatible. + Type '42' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(26,15): error TS2322: Type '{ naaaaaaame: "no"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. + Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(31,23): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { "prop-name": string; }'. + Type '{}' is not assignable to type '{ "prop-name": string; }'. + Property '"prop-name"' is missing in type '{}'. ==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== @@ -12,26 +19,44 @@ tests/cases/conformance/jsx/file.tsx(21,15): error TS2339: Property 'naaaaaaame' function Meet({name = 'world'}) { return
      Hello, {name}
      ; } + function MeetAndGreet(k: {"prop-name": string}) { + return
      Hi Hi
      ; + } // OK let a = ; + let a1 = ; // Error let b = ; - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2324: Property 'name' is missing in type 'IntrinsicAttributes & { name: string; }'. - ~~~~~~ -!!! error TS2339: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ naaame: "world"; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. +!!! error TS2322: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. // OK let c = ; + let c1 = ; // OK let d = ; // Error let e = ; ~~~~~~~~~ -!!! error TS2322: Type '42' is not assignable to type 'string'. +!!! error TS2322: Type '{ name: 42; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. +!!! error TS2322: Type '{ name: 42; }' is not assignable to type '{ name?: string; }'. +!!! error TS2322: Types of property 'name' are incompatible. +!!! error TS2322: Type '42' is not assignable to type 'string'. // Error let f = ; - ~~~~~~~~~~ -!!! error TS2339: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ naaaaaaame: "no"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. +!!! error TS2322: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. + + // OK + let g = ; + // Error + let h = ; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { "prop-name": string; }'. +!!! error TS2322: Type '{}' is not assignable to type '{ "prop-name": string; }'. +!!! error TS2322: Property '"prop-name"' is missing in type '{}'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.js b/tests/baselines/reference/tsxStatelessFunctionComponents1.js index 864e519f786c2..1f6a29736d76d 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.js @@ -6,20 +6,31 @@ function Greet(x: {name: string}) { function Meet({name = 'world'}) { return
      Hello, {name}
      ; } +function MeetAndGreet(k: {"prop-name": string}) { + return
      Hi Hi
      ; +} // OK let a = ; +let a1 = ; // Error let b = ; // OK let c = ; +let c1 = ; // OK let d = ; // Error let e = ; // Error let f = ; + +// OK +let g = ; +// Error +let h = ; + //// [file.jsx] @@ -30,15 +41,24 @@ function Meet(_a) { var _b = _a.name, name = _b === void 0 ? 'world' : _b; return
      Hello, {name}
      ; } +function MeetAndGreet(k) { + return
      Hi Hi
      ; +} // OK var a = ; +var a1 = ; // Error var b = ; // OK var c = ; +var c1 = ; // OK var d = ; // Error var e = ; // Error var f = ; +// OK +var g = ; +// Error +var h = ; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt index f8a569838ee45..6cefda87834df 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(20,16): error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(20,16): error TS2322: Type '{ ref: "myRef"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. + Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. tests/cases/conformance/jsx/file.tsx(26,42): error TS2339: Property 'subtr' does not exist on type 'string'. tests/cases/conformance/jsx/file.tsx(28,33): error TS2339: Property 'notARealProperty' does not exist on type 'BigGreeter'. tests/cases/conformance/jsx/file.tsx(36,26): error TS2339: Property 'propertyNotOnHtmlDivElement' does not exist on type 'HTMLDivElement'. @@ -25,8 +26,9 @@ tests/cases/conformance/jsx/file.tsx(36,26): error TS2339: Property 'propertyNot let b = ; // Error - not allowed to specify 'ref' on SFCs let c = ; - ~~~ -!!! error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. + ~~~~~~~~~~~ +!!! error TS2322: Type '{ ref: "myRef"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. +!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. // OK - ref is valid for classes diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols index 4ce502c6a6a08..d42d7aeaf1221 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponents3.symbols @@ -6,7 +6,7 @@ import React = require('react'); const Foo = (props: any) =>
      ; >Foo : Symbol(Foo, Decl(file.tsx, 3, 5)) >props : Symbol(props, Decl(file.tsx, 3, 13)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) // Should be OK const foo = ; @@ -18,31 +18,31 @@ const foo = ; var MainMenu: React.StatelessComponent<{}> = (props) => (
      >MainMenu : Symbol(MainMenu, Decl(file.tsx, 9, 3)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 139, 5)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) >props : Symbol(props, Decl(file.tsx, 9, 46)) ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45))

      Main Menu

      ->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 939, 48)) ->h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 939, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2409, 48)) +>h3 : Symbol(JSX.IntrinsicElements.h3, Decl(react.d.ts, 2409, 48))
      ); ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) var App: React.StatelessComponent<{ children }> = ({children}) => ( >App : Symbol(App, Decl(file.tsx, 13, 3)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 139, 5)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) >children : Symbol(children, Decl(file.tsx, 13, 35)) >children : Symbol(children, Decl(file.tsx, 13, 52))
      ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) >MainMenu : Symbol(MainMenu, Decl(file.tsx, 9, 3))
      ->div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 927, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2397, 45)) ); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.errors.txt new file mode 100644 index 0000000000000..dd628c6de0e9c --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.errors.txt @@ -0,0 +1,59 @@ +tests/cases/conformance/jsx/file.tsx(16,25): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(17,25): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(25,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(26,34): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(27,33): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/conformance/jsx/file.tsx (5 errors) ==== + + import React = require('react') + + + declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; + + // OK + function Baz(key1: T, value: U) { + let a0 = + let a1 = + } + + // OK + declare function Component(l: U): JSX.Element; + function createComponent(arg:T) { + let a1 = ; + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a2 = ; + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + declare function ComponentSpecific(l: {prop: U}): JSX.Element; + declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; + + // OK + function Bar(arg: T) { + let a1 = ; // U is number + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a2 = ; // U is number + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a3 = ; // U is "hello" + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + + // OK + function createLink(func: (a: number)=>void) { + let o = + } + + function createLink1(func: (a: number)=>boolean) { + let o = + } + + \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.js b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.js new file mode 100644 index 0000000000000..ab9171b8ed146 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.js @@ -0,0 +1,69 @@ +//// [file.tsx] + +import React = require('react') + + +declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; + +// OK +function Baz(key1: T, value: U) { + let a0 = + let a1 = +} + +// OK +declare function Component(l: U): JSX.Element; +function createComponent(arg:T) { + let a1 = ; + let a2 = ; +} + +declare function ComponentSpecific(l: {prop: U}): JSX.Element; +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; + +// OK +function Bar(arg: T) { + let a1 = ; // U is number + let a2 = ; // U is number + let a3 = ; // U is "hello" +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + +// OK +function createLink(func: (a: number)=>void) { + let o = +} + +function createLink1(func: (a: number)=>boolean) { + let o = +} + + + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + // OK + function Baz(key1, value) { + var a0 = ; + var a1 = ; + } + function createComponent(arg) { + var a1 = ; + var a2 = ; + } + // OK + function Bar(arg) { + var a1 = ; // U is number + var a2 = ; // U is number + var a3 = ; // U is "hello" + } + // OK + function createLink(func) { + var o = ; + } + function createLink1(func) { + var o = ; + } +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.symbols new file mode 100644 index 0000000000000..88654281891f4 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.symbols @@ -0,0 +1,154 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : Symbol(React, Decl(file.tsx, 0, 0)) + + +declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; +>ComponentWithTwoAttributes : Symbol(ComponentWithTwoAttributes, Decl(file.tsx, 1, 31)) +>K : Symbol(K, Decl(file.tsx, 4, 44)) +>V : Symbol(V, Decl(file.tsx, 4, 46)) +>l : Symbol(l, Decl(file.tsx, 4, 49)) +>key1 : Symbol(key1, Decl(file.tsx, 4, 53)) +>K : Symbol(K, Decl(file.tsx, 4, 44)) +>value : Symbol(value, Decl(file.tsx, 4, 61)) +>V : Symbol(V, Decl(file.tsx, 4, 46)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +function Baz(key1: T, value: U) { +>Baz : Symbol(Baz, Decl(file.tsx, 4, 86)) +>T : Symbol(T, Decl(file.tsx, 7, 13)) +>U : Symbol(U, Decl(file.tsx, 7, 15)) +>key1 : Symbol(key1, Decl(file.tsx, 7, 18)) +>T : Symbol(T, Decl(file.tsx, 7, 13)) +>value : Symbol(value, Decl(file.tsx, 7, 26)) +>U : Symbol(U, Decl(file.tsx, 7, 15)) + + let a0 = +>a0 : Symbol(a0, Decl(file.tsx, 8, 7)) +>ComponentWithTwoAttributes : Symbol(ComponentWithTwoAttributes, Decl(file.tsx, 1, 31)) +>key1 : Symbol(key1, Decl(file.tsx, 8, 40)) +>key1 : Symbol(key1, Decl(file.tsx, 7, 18)) +>value : Symbol(value, Decl(file.tsx, 8, 52)) +>value : Symbol(value, Decl(file.tsx, 7, 26)) + + let a1 = +>a1 : Symbol(a1, Decl(file.tsx, 9, 7)) +>ComponentWithTwoAttributes : Symbol(ComponentWithTwoAttributes, Decl(file.tsx, 1, 31)) +>key1 : Symbol(key1, Decl(file.tsx, 9, 46)) +>value : Symbol(value, Decl(file.tsx, 9, 51)) +>value : Symbol(value, Decl(file.tsx, 7, 26)) +>key : Symbol(key, Decl(file.tsx, 9, 66)) +} + +// OK +declare function Component(l: U): JSX.Element; +>Component : Symbol(Component, Decl(file.tsx, 10, 1)) +>U : Symbol(U, Decl(file.tsx, 13, 27)) +>l : Symbol(l, Decl(file.tsx, 13, 30)) +>U : Symbol(U, Decl(file.tsx, 13, 27)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +function createComponent(arg:T) { +>createComponent : Symbol(createComponent, Decl(file.tsx, 13, 49)) +>T : Symbol(T, Decl(file.tsx, 14, 25)) +>prop : Symbol(prop, Decl(file.tsx, 14, 36)) +>arg : Symbol(arg, Decl(file.tsx, 14, 51)) +>T : Symbol(T, Decl(file.tsx, 14, 25)) + + let a1 = ; +>a1 : Symbol(a1, Decl(file.tsx, 15, 7)) +>Component : Symbol(Component, Decl(file.tsx, 10, 1)) +>arg : Symbol(arg, Decl(file.tsx, 14, 51)) + + let a2 = ; +>a2 : Symbol(a2, Decl(file.tsx, 16, 7)) +>Component : Symbol(Component, Decl(file.tsx, 10, 1)) +>arg : Symbol(arg, Decl(file.tsx, 14, 51)) +>prop1 : Symbol(prop1, Decl(file.tsx, 16, 32)) +} + +declare function ComponentSpecific(l: {prop: U}): JSX.Element; +>ComponentSpecific : Symbol(ComponentSpecific, Decl(file.tsx, 17, 1)) +>U : Symbol(U, Decl(file.tsx, 19, 35)) +>l : Symbol(l, Decl(file.tsx, 19, 38)) +>prop : Symbol(prop, Decl(file.tsx, 19, 42)) +>U : Symbol(U, Decl(file.tsx, 19, 35)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; +>ComponentSpecific1 : Symbol(ComponentSpecific1, Decl(file.tsx, 19, 65)) +>U : Symbol(U, Decl(file.tsx, 20, 36)) +>l : Symbol(l, Decl(file.tsx, 20, 39)) +>prop : Symbol(prop, Decl(file.tsx, 20, 43)) +>U : Symbol(U, Decl(file.tsx, 20, 36)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +function Bar(arg: T) { +>Bar : Symbol(Bar, Decl(file.tsx, 20, 89)) +>T : Symbol(T, Decl(file.tsx, 23, 13)) +>prop : Symbol(prop, Decl(file.tsx, 23, 24)) +>arg : Symbol(arg, Decl(file.tsx, 23, 39)) +>T : Symbol(T, Decl(file.tsx, 23, 13)) + + let a1 = ; // U is number +>a1 : Symbol(a1, Decl(file.tsx, 24, 7)) +>ComponentSpecific : Symbol(ComponentSpecific, Decl(file.tsx, 17, 1)) +>arg : Symbol(arg, Decl(file.tsx, 23, 39)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 24, 40)) + + let a2 = ; // U is number +>a2 : Symbol(a2, Decl(file.tsx, 25, 7)) +>ComponentSpecific1 : Symbol(ComponentSpecific1, Decl(file.tsx, 19, 65)) +>arg : Symbol(arg, Decl(file.tsx, 23, 39)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 25, 41)) + + let a3 = ; // U is "hello" +>a3 : Symbol(a3, Decl(file.tsx, 26, 7)) +>ComponentSpecific : Symbol(ComponentSpecific, Decl(file.tsx, 17, 1)) +>arg : Symbol(arg, Decl(file.tsx, 23, 39)) +>prop : Symbol(prop, Decl(file.tsx, 26, 40)) +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +>Link : Symbol(Link, Decl(file.tsx, 27, 1)) +>U : Symbol(U, Decl(file.tsx, 29, 22)) +>l : Symbol(l, Decl(file.tsx, 29, 25)) +>func : Symbol(func, Decl(file.tsx, 29, 29)) +>arg : Symbol(arg, Decl(file.tsx, 29, 36)) +>U : Symbol(U, Decl(file.tsx, 29, 22)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +function createLink(func: (a: number)=>void) { +>createLink : Symbol(createLink, Decl(file.tsx, 29, 65)) +>func : Symbol(func, Decl(file.tsx, 32, 20)) +>a : Symbol(a, Decl(file.tsx, 32, 27)) + + let o = +>o : Symbol(o, Decl(file.tsx, 33, 7)) +>Link : Symbol(Link, Decl(file.tsx, 27, 1)) +>func : Symbol(func, Decl(file.tsx, 33, 17)) +>func : Symbol(func, Decl(file.tsx, 32, 20)) +} + +function createLink1(func: (a: number)=>boolean) { +>createLink1 : Symbol(createLink1, Decl(file.tsx, 34, 1)) +>func : Symbol(func, Decl(file.tsx, 36, 21)) +>a : Symbol(a, Decl(file.tsx, 36, 28)) + + let o = +>o : Symbol(o, Decl(file.tsx, 37, 7)) +>Link : Symbol(Link, Decl(file.tsx, 27, 1)) +>func : Symbol(func, Decl(file.tsx, 37, 17)) +>func : Symbol(func, Decl(file.tsx, 36, 21)) +} + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.types b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.types new file mode 100644 index 0000000000000..c1bf05c0fa53b --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments1.types @@ -0,0 +1,165 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : typeof React + + +declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; +>ComponentWithTwoAttributes : (l: { key1: K; value: V; }) => JSX.Element +>K : K +>V : V +>l : { key1: K; value: V; } +>key1 : K +>K : K +>value : V +>V : V +>JSX : any +>Element : JSX.Element + +// OK +function Baz(key1: T, value: U) { +>Baz : (key1: T, value: U) => void +>T : T +>U : U +>key1 : T +>T : T +>value : U +>U : U + + let a0 = +>a0 : JSX.Element +> : JSX.Element +>ComponentWithTwoAttributes : (l: { key1: K; value: V; }) => JSX.Element +>key1 : T +>key1 : T +>value : U +>value : U + + let a1 = +>a1 : JSX.Element +> : JSX.Element +>ComponentWithTwoAttributes : (l: { key1: K; value: V; }) => JSX.Element +>{key1, value: value} : { key1: T; value: U; } +>key1 : T +>value : U +>value : U +>key : string +} + +// OK +declare function Component(l: U): JSX.Element; +>Component : (l: U) => JSX.Element +>U : U +>l : U +>U : U +>JSX : any +>Element : JSX.Element + +function createComponent(arg:T) { +>createComponent : (arg: T) => void +>T : T +>prop : number +>arg : T +>T : T + + let a1 = ; +>a1 : JSX.Element +> : JSX.Element +>Component : (l: U) => JSX.Element +>arg : T + + let a2 = ; +>a2 : JSX.Element +> : JSX.Element +>Component : (l: U) => JSX.Element +>arg : T +>prop1 : true +} + +declare function ComponentSpecific(l: {prop: U}): JSX.Element; +>ComponentSpecific : (l: { prop: U; }) => JSX.Element +>U : U +>l : { prop: U; } +>prop : U +>U : U +>JSX : any +>Element : JSX.Element + +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; +>ComponentSpecific1 : (l: { prop: U; "ignore-prop": number; }) => JSX.Element +>U : U +>l : { prop: U; "ignore-prop": number; } +>prop : U +>U : U +>JSX : any +>Element : JSX.Element + +// OK +function Bar(arg: T) { +>Bar : (arg: T) => void +>T : T +>prop : number +>arg : T +>T : T + + let a1 = ; // U is number +>a1 : JSX.Element +> : JSX.Element +>ComponentSpecific : (l: { prop: U; }) => JSX.Element +>arg : T +>ignore-prop : string + + let a2 = ; // U is number +>a2 : JSX.Element +> : JSX.Element +>ComponentSpecific1 : (l: { prop: U; "ignore-prop": number; }) => JSX.Element +>arg : T +>ignore-prop : number +>10 : 10 + + let a3 = ; // U is "hello" +>a3 : JSX.Element +> : JSX.Element +>ComponentSpecific : (l: { prop: U; }) => JSX.Element +>arg : T +>prop : string +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +>Link : (l: { func: (arg: U) => void; }) => JSX.Element +>U : U +>l : { func: (arg: U) => void; } +>func : (arg: U) => void +>arg : U +>U : U +>JSX : any +>Element : JSX.Element + +// OK +function createLink(func: (a: number)=>void) { +>createLink : (func: (a: number) => void) => void +>func : (a: number) => void +>a : number + + let o = +>o : JSX.Element +> : JSX.Element +>Link : (l: { func: (arg: U) => void; }) => JSX.Element +>func : (a: number) => void +>func : (a: number) => void +} + +function createLink1(func: (a: number)=>boolean) { +>createLink1 : (func: (a: number) => boolean) => void +>func : (a: number) => boolean +>a : number + + let o = +>o : JSX.Element +> : JSX.Element +>Link : (l: { func: (arg: U) => void; }) => JSX.Element +>func : (a: number) => boolean +>func : (a: number) => boolean +} + + diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt new file mode 100644 index 0000000000000..98fa75d99a17f --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/jsx/file.tsx(9,34): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(14,34): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(21,19): error TS2322: Type '{ func: (a: number, b: string) => void; }' is not assignable to type 'IntrinsicAttributes & { func: (arg: number) => void; }'. + Type '{ func: (a: number, b: string) => void; }' is not assignable to type '{ func: (arg: number) => void; }'. + Types of property 'func' are incompatible. + Type '(a: number, b: string) => void' is not assignable to type '(arg: number) => void'. + + +==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== + + import React = require('react') + + declare function ComponentSpecific1(l: {prop: U, "ignore-prop": string}): JSX.Element; + declare function ComponentSpecific2(l: {prop: U}): JSX.Element; + + // Error + function Bar(arg: T) { + let a1 = ; + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + // Error + function Baz(arg: T) { + let a0 = + ~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + + // Error + function createLink(func: (a: number, b: string)=>void) { + let o = + ~~~~~~~~~~~ +!!! error TS2322: Type '{ func: (a: number, b: string) => void; }' is not assignable to type 'IntrinsicAttributes & { func: (arg: number) => void; }'. +!!! error TS2322: Type '{ func: (a: number, b: string) => void; }' is not assignable to type '{ func: (arg: number) => void; }'. +!!! error TS2322: Types of property 'func' are incompatible. +!!! error TS2322: Type '(a: number, b: string) => void' is not assignable to type '(arg: number) => void'. + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.js b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.js new file mode 100644 index 0000000000000..a42f7ac176837 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.js @@ -0,0 +1,40 @@ +//// [file.tsx] + +import React = require('react') + +declare function ComponentSpecific1(l: {prop: U, "ignore-prop": string}): JSX.Element; +declare function ComponentSpecific2(l: {prop: U}): JSX.Element; + +// Error +function Bar(arg: T) { + let a1 = ; + } + +// Error +function Baz(arg: T) { + let a0 = +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + +// Error +function createLink(func: (a: number, b: string)=>void) { + let o = +} + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + // Error + function Bar(arg) { + var a1 = ; + } + // Error + function Baz(arg) { + var a0 = ; + } + // Error + function createLink(func) { + var o = ; + } +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.errors.txt new file mode 100644 index 0000000000000..53d11be4ef96d --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/jsx/file.tsx(10,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(11,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(12,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(13,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(15,33): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/jsx/file.tsx(16,33): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/conformance/jsx/file.tsx (6 errors) ==== + + import React = require('react') + + declare function OverloadComponent(): JSX.Element; + declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; + declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + + // OK + function Baz(arg1: T, arg2: U) { + let a0 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a1 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a2 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a3 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a4 = ; + let a5 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + let a6 = ; + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } + + declare function Link(l: {func: (arg: U)=>void}): JSX.Element; + declare function Link(l: {func: (arg1:U, arg2: string)=>void}): JSX.Element; + function createLink(func: (a: number)=>void) { + let o = + let o1 = {}} />; + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.js b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.js new file mode 100644 index 0000000000000..8eaf5d2015e93 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.js @@ -0,0 +1,44 @@ +//// [file.tsx] + +import React = require('react') + +declare function OverloadComponent(): JSX.Element; +declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + +// OK +function Baz(arg1: T, arg2: U) { + let a0 = ; + let a1 = ; + let a2 = ; + let a3 = ; + let a4 = ; + let a5 = ; + let a6 = ; +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +declare function Link(l: {func: (arg1:U, arg2: string)=>void}): JSX.Element; +function createLink(func: (a: number)=>void) { + let o = + let o1 = {}} />; +} + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + // OK + function Baz(arg1, arg2) { + var a0 = ; + var a1 = ; + var a2 = ; + var a3 = ; + var a4 = ; + var a5 = ; + var a6 = ; + } + function createLink(func) { + var o = ; + var o1 = ; + } +}); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.symbols new file mode 100644 index 0000000000000..ebd80b3d262d6 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.symbols @@ -0,0 +1,128 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +declare function OverloadComponent(): JSX.Element; +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>U : Symbol(U, Decl(file.tsx, 3, 35)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>U : Symbol(U, Decl(file.tsx, 4, 35)) +>attr : Symbol(attr, Decl(file.tsx, 4, 38)) +>b : Symbol(b, Decl(file.tsx, 4, 45)) +>U : Symbol(U, Decl(file.tsx, 4, 35)) +>a : Symbol(a, Decl(file.tsx, 4, 50)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>T : Symbol(T, Decl(file.tsx, 5, 35)) +>U : Symbol(U, Decl(file.tsx, 5, 37)) +>attr : Symbol(attr, Decl(file.tsx, 5, 41)) +>b : Symbol(b, Decl(file.tsx, 5, 48)) +>U : Symbol(U, Decl(file.tsx, 5, 37)) +>a : Symbol(a, Decl(file.tsx, 5, 53)) +>T : Symbol(T, Decl(file.tsx, 5, 35)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +// OK +function Baz(arg1: T, arg2: U) { +>Baz : Symbol(Baz, Decl(file.tsx, 5, 74)) +>T : Symbol(T, Decl(file.tsx, 8, 13)) +>b : Symbol(b, Decl(file.tsx, 8, 24)) +>U : Symbol(U, Decl(file.tsx, 8, 35)) +>a : Symbol(a, Decl(file.tsx, 8, 47)) +>b : Symbol(b, Decl(file.tsx, 8, 58)) +>arg1 : Symbol(arg1, Decl(file.tsx, 8, 70)) +>T : Symbol(T, Decl(file.tsx, 8, 13)) +>arg2 : Symbol(arg2, Decl(file.tsx, 8, 78)) +>U : Symbol(U, Decl(file.tsx, 8, 35)) + + let a0 = ; +>a0 : Symbol(a0, Decl(file.tsx, 9, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg1 : Symbol(arg1, Decl(file.tsx, 8, 70)) +>a : Symbol(a, Decl(file.tsx, 9, 41)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 9, 51)) + + let a1 = ; +>a1 : Symbol(a1, Decl(file.tsx, 10, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg2 : Symbol(arg2, Decl(file.tsx, 8, 78)) +>ignore-pro : Symbol(ignore-pro, Decl(file.tsx, 10, 41)) + + let a2 = ; +>a2 : Symbol(a2, Decl(file.tsx, 11, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg2 : Symbol(arg2, Decl(file.tsx, 8, 78)) + + let a3 = ; +>a3 : Symbol(a3, Decl(file.tsx, 12, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg1 : Symbol(arg1, Decl(file.tsx, 8, 70)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 12, 41)) + + let a4 = ; +>a4 : Symbol(a4, Decl(file.tsx, 13, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) + + let a5 = ; +>a5 : Symbol(a5, Decl(file.tsx, 14, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg2 : Symbol(arg2, Decl(file.tsx, 8, 78)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 14, 41)) +>arg1 : Symbol(arg1, Decl(file.tsx, 8, 70)) + + let a6 = ; +>a6 : Symbol(a6, Decl(file.tsx, 15, 7)) +>OverloadComponent : Symbol(OverloadComponent, Decl(file.tsx, 1, 31), Decl(file.tsx, 3, 53), Decl(file.tsx, 4, 101)) +>arg2 : Symbol(arg2, Decl(file.tsx, 8, 78)) +>ignore-prop : Symbol(ignore-prop, Decl(file.tsx, 15, 41)) +>arg1 : Symbol(arg1, Decl(file.tsx, 8, 70)) +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +>Link : Symbol(Link, Decl(file.tsx, 16, 1), Decl(file.tsx, 18, 65)) +>U : Symbol(U, Decl(file.tsx, 18, 22)) +>l : Symbol(l, Decl(file.tsx, 18, 25)) +>func : Symbol(func, Decl(file.tsx, 18, 29)) +>arg : Symbol(arg, Decl(file.tsx, 18, 36)) +>U : Symbol(U, Decl(file.tsx, 18, 22)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +declare function Link(l: {func: (arg1:U, arg2: string)=>void}): JSX.Element; +>Link : Symbol(Link, Decl(file.tsx, 16, 1), Decl(file.tsx, 18, 65)) +>U : Symbol(U, Decl(file.tsx, 19, 22)) +>l : Symbol(l, Decl(file.tsx, 19, 25)) +>func : Symbol(func, Decl(file.tsx, 19, 29)) +>arg1 : Symbol(arg1, Decl(file.tsx, 19, 36)) +>U : Symbol(U, Decl(file.tsx, 19, 22)) +>arg2 : Symbol(arg2, Decl(file.tsx, 19, 43)) +>JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) +>Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) + +function createLink(func: (a: number)=>void) { +>createLink : Symbol(createLink, Decl(file.tsx, 19, 79)) +>func : Symbol(func, Decl(file.tsx, 20, 20)) +>a : Symbol(a, Decl(file.tsx, 20, 27)) + + let o = +>o : Symbol(o, Decl(file.tsx, 21, 7)) +>Link : Symbol(Link, Decl(file.tsx, 16, 1), Decl(file.tsx, 18, 65)) +>func : Symbol(func, Decl(file.tsx, 21, 17)) +>func : Symbol(func, Decl(file.tsx, 20, 20)) + + let o1 = {}} />; +>o1 : Symbol(o1, Decl(file.tsx, 22, 7)) +>Link : Symbol(Link, Decl(file.tsx, 16, 1), Decl(file.tsx, 18, 65)) +>func : Symbol(func, Decl(file.tsx, 22, 18)) +>a : Symbol(a, Decl(file.tsx, 22, 26)) +>b : Symbol(b, Decl(file.tsx, 22, 35)) +} diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types new file mode 100644 index 0000000000000..f85638d0eddd5 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types @@ -0,0 +1,138 @@ +=== tests/cases/conformance/jsx/file.tsx === + +import React = require('react') +>React : typeof React + +declare function OverloadComponent(): JSX.Element; +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>U : U +>JSX : any +>Element : JSX.Element + +declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>U : U +>attr : { b: U; a?: string; "ignore-prop": boolean; } +>b : U +>U : U +>a : string +>JSX : any +>Element : JSX.Element + +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>T : T +>U : U +>attr : { b: U; a: T; } +>b : U +>U : U +>a : T +>T : T +>JSX : any +>Element : JSX.Element + +// OK +function Baz(arg1: T, arg2: U) { +>Baz : (arg1: T, arg2: U) => void +>T : T +>b : number +>U : U +>a : boolean +>b : string +>arg1 : T +>T : T +>arg2 : U +>U : U + + let a0 = ; +>a0 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg1 : T +>a : string +>ignore-prop : true + + let a1 = ; +>a1 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg2 : U +>ignore-pro : string + + let a2 = ; +>a2 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg2 : U + + let a3 = ; +>a3 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg1 : T +>ignore-prop : true + + let a4 = ; +>a4 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } + + let a5 = ; +>a5 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg2 : U +>ignore-prop : string +>arg1 : T + + let a6 = ; +>a6 : JSX.Element +> : JSX.Element +>OverloadComponent : { (): JSX.Element; (attr: { b: U; a?: string; "ignore-prop": boolean; }): JSX.Element; (attr: { b: U; a: T; }): JSX.Element; } +>arg2 : U +>ignore-prop : true +>arg1 : T +} + +declare function Link(l: {func: (arg: U)=>void}): JSX.Element; +>Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } +>U : U +>l : { func: (arg: U) => void; } +>func : (arg: U) => void +>arg : U +>U : U +>JSX : any +>Element : JSX.Element + +declare function Link(l: {func: (arg1:U, arg2: string)=>void}): JSX.Element; +>Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } +>U : U +>l : { func: (arg1: U, arg2: string) => void; } +>func : (arg1: U, arg2: string) => void +>arg1 : U +>U : U +>arg2 : string +>JSX : any +>Element : JSX.Element + +function createLink(func: (a: number)=>void) { +>createLink : (func: (a: number) => void) => void +>func : (a: number) => void +>a : number + + let o = +>o : JSX.Element +> : JSX.Element +>Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } +>func : (a: number) => void +>func : (a: number) => void + + let o1 = {}} />; +>o1 : JSX.Element +>{}} /> : JSX.Element +>Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } +>func : (a: number, b: string) => void +>(a:number, b:string)=>{} : (a: number, b: string) => void +>a : number +>b : string +} diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt new file mode 100644 index 0000000000000..4c1e768d04d95 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type '{ a: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: number; }'. + Type '{ a: number; }' is not assignable to type '{ b: {}; a: number; }'. + Property 'b' is missing in type '{ a: number; }'. +tests/cases/conformance/jsx/file.tsx(11,33): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== + + import React = require('react') + + declare function OverloadComponent(): JSX.Element; + declare function OverloadComponent(attr: {b: U, a: string, "ignore-prop": boolean}): JSX.Element; + declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + + // Error + function Baz(arg1: T, arg2: U) { + let a0 = + ~~~~~~~~~~ +!!! error TS2322: Type '{ a: number; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: number; }'. +!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ b: {}; a: number; }'. +!!! error TS2322: Property 'b' is missing in type '{ a: number; }'. + let a2 = // missing a + ~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.js b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.js new file mode 100644 index 0000000000000..63d24e3ab6af7 --- /dev/null +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.js @@ -0,0 +1,23 @@ +//// [file.tsx] + +import React = require('react') + +declare function OverloadComponent(): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: string, "ignore-prop": boolean}): JSX.Element; +declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + +// Error +function Baz(arg1: T, arg2: U) { + let a0 = + let a2 = // missing a +} + +//// [file.jsx] +define(["require", "exports", "react"], function (require, exports, React) { + "use strict"; + // Error + function Baz(arg1, arg2) { + var a0 = ; + var a2 = ; // missing a + } +}); diff --git a/tests/baselines/reference/tsxTypeErrors.symbols b/tests/baselines/reference/tsxTypeErrors.symbols index 062442cda1604..52a2d6a757444 100644 --- a/tests/baselines/reference/tsxTypeErrors.symbols +++ b/tests/baselines/reference/tsxTypeErrors.symbols @@ -4,13 +4,13 @@ var a1 =
      ; >a1 : Symbol(a1, Decl(tsxTypeErrors.tsx, 2, 3)) >div : Symbol(unknown) ->id : Symbol(unknown) +>id : Symbol(id, Decl(tsxTypeErrors.tsx, 2, 13)) // A built-in element with a mistyped property (error) var a2 = >a2 : Symbol(a2, Decl(tsxTypeErrors.tsx, 5, 3)) >img : Symbol(unknown) ->srce : Symbol(unknown) +>srce : Symbol(srce, Decl(tsxTypeErrors.tsx, 5, 13)) // A built-in element with a badly-typed attribute value (error) var thing = { oops: 100 }; @@ -20,14 +20,14 @@ var thing = { oops: 100 }; var a3 =
      >a3 : Symbol(a3, Decl(tsxTypeErrors.tsx, 9, 3)) >div : Symbol(unknown) ->id : Symbol(unknown) +>id : Symbol(id, Decl(tsxTypeErrors.tsx, 9, 13)) >thing : Symbol(thing, Decl(tsxTypeErrors.tsx, 8, 3)) // Mistyped html name (error) var e1 = >e1 : Symbol(e1, Decl(tsxTypeErrors.tsx, 12, 3)) >imag : Symbol(unknown) ->src : Symbol(unknown) +>src : Symbol(src, Decl(tsxTypeErrors.tsx, 12, 14)) // A custom type class MyClass { @@ -54,7 +54,7 @@ class MyClass { var b1 = ; >b1 : Symbol(b1, Decl(tsxTypeErrors.tsx, 25, 3)) >MyClass : Symbol(MyClass, Decl(tsxTypeErrors.tsx, 12, 31)) ->reqd : Symbol(unknown) +>reqd : Symbol(reqd, Decl(tsxTypeErrors.tsx, 25, 17)) // Mistyped attribute member // sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. @@ -63,7 +63,7 @@ var b1 = ; var b2 = ; >b2 : Symbol(b2, Decl(tsxTypeErrors.tsx, 31, 3)) >MyClass : Symbol(MyClass, Decl(tsxTypeErrors.tsx, 12, 31)) ->pt : Symbol(unknown) +>pt : Symbol(pt, Decl(tsxTypeErrors.tsx, 31, 17)) >x : Symbol(x, Decl(tsxTypeErrors.tsx, 31, 23)) >y : Symbol(y, Decl(tsxTypeErrors.tsx, 31, 28)) diff --git a/tests/baselines/reference/tsxTypeErrors.types b/tests/baselines/reference/tsxTypeErrors.types index d64781479fa27..f20c16dca163a 100644 --- a/tests/baselines/reference/tsxTypeErrors.types +++ b/tests/baselines/reference/tsxTypeErrors.types @@ -5,14 +5,14 @@ var a1 =
      ; >a1 : any >
      : any >div : any ->id : any +>id : string // A built-in element with a mistyped property (error) var a2 = >a2 : any > : any >img : any ->srce : any +>srce : string // A built-in element with a badly-typed attribute value (error) var thing = { oops: 100 }; @@ -25,7 +25,7 @@ var a3 =
      >a3 : any >
      : any >div : any ->id : any +>id : { oops: number; } >thing : { oops: number; } // Mistyped html name (error) @@ -33,7 +33,7 @@ var e1 = >e1 : any > : any >imag : any ->src : any +>src : string // A custom type class MyClass { @@ -61,7 +61,7 @@ var b1 = ; >b1 : any > : any >MyClass : typeof MyClass ->reqd : any +>reqd : boolean >true : true // Mistyped attribute member @@ -72,7 +72,7 @@ var b2 = ; >b2 : any > : any >MyClass : typeof MyClass ->pt : any +>pt : { x: number; y: string; } >{x: 4, y: 'oops'} : { x: number; y: string; } >x : number >4 : 4 diff --git a/tests/baselines/reference/tsxUnionTypeComponent1.symbols b/tests/baselines/reference/tsxUnionTypeComponent1.symbols index 73f7180f3b8cd..be4bc204da3ea 100644 --- a/tests/baselines/reference/tsxUnionTypeComponent1.symbols +++ b/tests/baselines/reference/tsxUnionTypeComponent1.symbols @@ -9,16 +9,16 @@ interface ComponentProps { AnyComponent: React.StatelessComponent | React.ComponentClass; >AnyComponent : Symbol(ComponentProps.AnyComponent, Decl(file.tsx, 3, 26)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 139, 5)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react.d.ts, 197, 40)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 150, 5)) +>ComponentClass : Symbol(React.ComponentClass, Decl(react.d.ts, 204, 5)) } class MyComponent extends React.Component { >MyComponent : Symbol(MyComponent, Decl(file.tsx, 5, 1)) ->React.Component : Symbol(React.Component, Decl(react.d.ts, 114, 55)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->Component : Symbol(React.Component, Decl(react.d.ts, 114, 55)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) >ComponentProps : Symbol(ComponentProps, Decl(file.tsx, 1, 32)) render() { @@ -26,9 +26,9 @@ class MyComponent extends React.Component { const { AnyComponent } = this.props; >AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 9, 15)) ->this.props : Symbol(React.Component.props, Decl(react.d.ts, 122, 30)) +>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) >this : Symbol(MyComponent, Decl(file.tsx, 5, 1)) ->props : Symbol(React.Component.props, Decl(react.d.ts, 122, 30)) +>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) return (); >AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 9, 15)) @@ -38,21 +38,21 @@ class MyComponent extends React.Component { // Stateless Component As Props }/> >MyComponent : Symbol(MyComponent, Decl(file.tsx, 5, 1)) ->AnyComponent : Symbol(ComponentProps.AnyComponent, Decl(file.tsx, 3, 26)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 913, 43)) ->button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 913, 43)) +>AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 15, 12)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2383, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2383, 43)) // Component Class as Props class MyButtonComponent extends React.Component<{},{}> { >MyButtonComponent : Symbol(MyButtonComponent, Decl(file.tsx, 15, 57)) ->React.Component : Symbol(React.Component, Decl(react.d.ts, 114, 55)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) >React : Symbol(React, Decl(file.tsx, 0, 0)) ->Component : Symbol(React.Component, Decl(react.d.ts, 114, 55)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) } >MyComponent : Symbol(MyComponent, Decl(file.tsx, 5, 1)) ->AnyComponent : Symbol(ComponentProps.AnyComponent, Decl(file.tsx, 3, 26)) +>AnyComponent : Symbol(AnyComponent, Decl(file.tsx, 21, 12)) >MyButtonComponent : Symbol(MyButtonComponent, Decl(file.tsx, 15, 57)) diff --git a/tests/baselines/reference/tsxUnionTypeComponent1.types b/tests/baselines/reference/tsxUnionTypeComponent1.types index ce6e3bbeecc6c..c3f4c70a30715 100644 --- a/tests/baselines/reference/tsxUnionTypeComponent1.types +++ b/tests/baselines/reference/tsxUnionTypeComponent1.types @@ -26,9 +26,9 @@ class MyComponent extends React.Component { const { AnyComponent } = this.props; >AnyComponent : React.StatelessComponent | React.ComponentClass ->this.props : ComponentProps +>this.props : ComponentProps & { children?: React.ReactNode; } >this : this ->props : ComponentProps +>props : ComponentProps & { children?: React.ReactNode; } return (); >() : JSX.Element @@ -41,7 +41,7 @@ class MyComponent extends React.Component { }/> > }/> : JSX.Element >MyComponent : typeof MyComponent ->AnyComponent : any +>AnyComponent : () => JSX.Element >() => : () => JSX.Element > : JSX.Element >button : any @@ -58,7 +58,7 @@ class MyButtonComponent extends React.Component<{},{}> { > : JSX.Element >MyComponent : typeof MyComponent ->AnyComponent : any +>AnyComponent : typeof MyButtonComponent >MyButtonComponent : typeof MyButtonComponent From 03a57b21b399a2f311f63a0a60030fd525d2bd7c Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 8 Nov 2016 11:07:17 -0800 Subject: [PATCH 14/25] Add language service tests --- .../goToDefinitionObjectLiteralProperties1.ts | 19 ++++++ tests/cases/fourslash/tsxCompletion12.ts | 47 ++++++++++++++ tests/cases/fourslash/tsxCompletion13.ts | 62 +++++++++++++++++++ .../cases/fourslash/tsxFindAllReferences1.ts | 16 +++++ .../cases/fourslash/tsxFindAllReferences10.ts | 33 ++++++++++ .../cases/fourslash/tsxFindAllReferences11.ts | 29 +++++++++ .../cases/fourslash/tsxFindAllReferences2.ts | 16 +++++ .../cases/fourslash/tsxFindAllReferences3.ts | 19 ++++++ .../cases/fourslash/tsxFindAllReferences4.ts | 19 ++++++ .../cases/fourslash/tsxFindAllReferences5.ts | 25 ++++++++ .../cases/fourslash/tsxFindAllReferences6.ts | 23 +++++++ .../cases/fourslash/tsxFindAllReferences7.ts | 24 +++++++ .../cases/fourslash/tsxFindAllReferences8.ts | 33 ++++++++++ .../cases/fourslash/tsxFindAllReferences9.ts | 34 ++++++++++ .../fourslash/tsxGoToDefinitionClasses.ts | 4 +- .../tsxGoToDefinitionStatelessFunction1.ts | 31 ++++++++++ .../tsxGoToDefinitionStatelessFunction2.ts | 40 ++++++++++++ tests/cases/fourslash/tsxQuickInfo3.ts | 30 +++++++++ tests/cases/fourslash/tsxQuickInfo4.ts | 55 ++++++++++++++++ tests/cases/fourslash/tsxQuickInfo5.ts | 18 ++++++ tests/cases/fourslash/tsxQuickInfo6.ts | 19 ++++++ tests/cases/fourslash/tsxQuickInfo7.ts | 29 +++++++++ tests/cases/fourslash/tsxRename10.ts | 40 ++++++++++++ tests/cases/fourslash/tsxRename11.ts | 39 ++++++++++++ tests/cases/fourslash/tsxRename12.ts | 39 ++++++++++++ tests/cases/fourslash/tsxRename13.ts | 39 ++++++++++++ tests/cases/fourslash/tsxRename6.ts | 30 +++++++++ tests/cases/fourslash/tsxRename7.ts | 29 +++++++++ tests/cases/fourslash/tsxRename8.ts | 31 ++++++++++ tests/cases/fourslash/tsxRename9.ts | 38 ++++++++++++ tests/cases/fourslash/tsxSignatureHelp1.ts | 35 +++++++++++ tests/cases/fourslash/tsxSignatureHelp2.ts | 42 +++++++++++++ 32 files changed, 986 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts create mode 100644 tests/cases/fourslash/tsxCompletion12.ts create mode 100644 tests/cases/fourslash/tsxCompletion13.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences1.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences10.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences11.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences2.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences3.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences4.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences5.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences6.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences7.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences8.ts create mode 100644 tests/cases/fourslash/tsxFindAllReferences9.ts create mode 100644 tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts create mode 100644 tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts create mode 100644 tests/cases/fourslash/tsxQuickInfo3.ts create mode 100644 tests/cases/fourslash/tsxQuickInfo4.ts create mode 100644 tests/cases/fourslash/tsxQuickInfo5.ts create mode 100644 tests/cases/fourslash/tsxQuickInfo6.ts create mode 100644 tests/cases/fourslash/tsxQuickInfo7.ts create mode 100644 tests/cases/fourslash/tsxRename10.ts create mode 100644 tests/cases/fourslash/tsxRename11.ts create mode 100644 tests/cases/fourslash/tsxRename12.ts create mode 100644 tests/cases/fourslash/tsxRename13.ts create mode 100644 tests/cases/fourslash/tsxRename6.ts create mode 100644 tests/cases/fourslash/tsxRename7.ts create mode 100644 tests/cases/fourslash/tsxRename8.ts create mode 100644 tests/cases/fourslash/tsxRename9.ts create mode 100644 tests/cases/fourslash/tsxSignatureHelp1.ts create mode 100644 tests/cases/fourslash/tsxSignatureHelp2.ts diff --git a/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts new file mode 100644 index 0000000000000..a1c22ca4ca395 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionObjectLiteralProperties1.ts @@ -0,0 +1,19 @@ +/// + +//// interface PropsBag { +//// /*first*/propx: number +//// } +//// function foo(arg: PropsBag) {} +//// foo({ +//// pr/*p1*/opx: 10 +//// }) +//// function bar(firstarg: boolean, secondarg: PropsBag) {} +//// bar(true, { +//// pr/*p2*/opx: 10 +//// }) + + +verify.goToDefinition({ + p1: "first", + p2: "first" +}); diff --git a/tests/cases/fourslash/tsxCompletion12.ts b/tests/cases/fourslash/tsxCompletion12.ts new file mode 100644 index 0000000000000..542dbec2c2b7b --- /dev/null +++ b/tests/cases/fourslash/tsxCompletion12.ts @@ -0,0 +1,47 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// propx: number +//// propString: "hell" +//// optional?: boolean +//// } +//// declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; +//// let opt1 = ; +//// let opt2 = ; +//// let opt3 = ; +//// let opt4 = ; + +goTo.marker("1"); +verify.completionListContains('propx'); +verify.completionListContains('propString'); +verify.completionListContains('optional'); + +goTo.marker("2"); +verify.completionListContains('propx'); +verify.completionListContains('propString'); + +goTo.marker("3"); +verify.completionListContains("propString") +verify.completionListContains("optional") +verify.not.completionListContains("propx") + +goTo.marker("4"); +verify.completionListContains("propString"); +verify.not.completionListContains("propx"); +verify.not.completionListContains("optional"); + +goTo.marker("5"); +verify.completionListContains('propx'); +verify.completionListContains('propString'); +verify.completionListContains('optional'); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxCompletion13.ts b/tests/cases/fourslash/tsxCompletion13.ts new file mode 100644 index 0000000000000..60964acbc5530 --- /dev/null +++ b/tests/cases/fourslash/tsxCompletion13.ts @@ -0,0 +1,62 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} /*3*/ />; +//// let opt = {}} ignore-prop /*4*/ />; +//// let opt = ; +//// let opt = ; + +goTo.marker("1"); +verify.completionListContains('children'); +verify.completionListContains('className'); +verify.completionListContains('onClick'); +verify.completionListContains('goTo'); + +goTo.marker("2"); +verify.completionListContains('className'); +verify.completionListContains('onClick'); +verify.completionListContains('goTo'); + +goTo.marker("3"); +verify.completionListContains('children'); +verify.completionListContains('className'); +verify.not.completionListContains('goTo'); + +goTo.marker("4"); +verify.completionListContains('children'); +verify.completionListContains('className'); + +goTo.marker("5"); +verify.completionListContains('children'); +verify.completionListContains('className'); +verify.not.completionListContains('onClick'); + +goTo.marker("6"); +verify.completionListContains('children'); +verify.completionListContains('className'); +verify.completionListContains('onClick'); +verify.completionListContains('goTo'); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences1.ts b/tests/cases/fourslash/tsxFindAllReferences1.ts new file mode 100644 index 0000000000000..9b55901ba68c9 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences1.ts @@ -0,0 +1,16 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// [|div|]: { +//// name?: string; +//// isOpen?: boolean; +//// }; +//// span: { n: string; }; +//// } +//// } +//// var x = <[|div|] />; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences10.ts b/tests/cases/fourslash/tsxFindAllReferences10.ts new file mode 100644 index 0000000000000..a027671ec3d4d --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences10.ts @@ -0,0 +1,33 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// [|onClick|](event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} ignore-prop />; +//// let opt = ; +//// let opt = ; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences11.ts b/tests/cases/fourslash/tsxFindAllReferences11.ts new file mode 100644 index 0000000000000..ef2f7722243ed --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences11.ts @@ -0,0 +1,29 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; // r1 + +const [r1] = test.ranges(); +verify.referencesOf(r1, [r1]); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences2.ts b/tests/cases/fourslash/tsxFindAllReferences2.ts new file mode 100644 index 0000000000000..8522874865a59 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences2.ts @@ -0,0 +1,16 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// div: { +//// [|name|]?: string; +//// isOpen?: boolean; +//// }; +//// span: { n: string; }; +//// } +//// } +//// var x =
      ; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences3.ts b/tests/cases/fourslash/tsxFindAllReferences3.ts new file mode 100644 index 0000000000000..2f78cc08ba979 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences3.ts @@ -0,0 +1,19 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props } +//// } +//// class MyClass { +//// props: { +//// [|name|]?: string; +//// size?: number; +//// } +//// +//// +//// var x = ; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences4.ts b/tests/cases/fourslash/tsxFindAllReferences4.ts new file mode 100644 index 0000000000000..a1309bfaef961 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences4.ts @@ -0,0 +1,19 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props } +//// } +//// class [|MyClass|] { +//// props: { +//// name?: string; +//// size?: number; +//// } +//// +//// +//// var x = <[|MyClass|] name='hello'>; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences5.ts b/tests/cases/fourslash/tsxFindAllReferences5.ts new file mode 100644 index 0000000000000..018b7568df15a --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences5.ts @@ -0,0 +1,25 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// propx: number +//// propString: string +//// optional?: boolean +//// } +//// declare function [|Opt|](attributes: OptionPropBag): JSX.Element; +//// let opt = <[|Opt|] />; +//// let opt1 = <[|Opt|] propx={100} propString />; +//// let opt2 = <[|Opt|] propx={100} optional/>; +//// let opt3 = <[|Opt|] wrong />; +//// let opt4 = <[|Opt|] propx={100} propString="hi" />; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences6.ts b/tests/cases/fourslash/tsxFindAllReferences6.ts new file mode 100644 index 0000000000000..ad689a53baff1 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences6.ts @@ -0,0 +1,23 @@ +/// +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// propx: number +//// propString: string +//// optional?: boolean +//// } +//// declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; //r1 + +const [r1] = test.ranges(); +verify.referencesOf(r1, [r1]); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences7.ts b/tests/cases/fourslash/tsxFindAllReferences7.ts new file mode 100644 index 0000000000000..b1f5231a19859 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences7.ts @@ -0,0 +1,24 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// [|propx|]: number +//// propString: string +//// optional?: boolean +//// } +//// declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; +//// let opt1 = ; +//// let opt2 = ; +//// let opt3 = ; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences8.ts b/tests/cases/fourslash/tsxFindAllReferences8.ts new file mode 100644 index 0000000000000..434e8cf330380 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences8.ts @@ -0,0 +1,33 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function [|MainButton|](buttonProps: ButtonProps): JSX.Element; +//// declare function [|MainButton|](linkProps: LinkProps): JSX.Element; +//// declare function [|MainButton|](props: ButtonProps | LinkProps): JSX.Element; +//// let opt = <[|MainButton|] />; +//// let opt = <[|MainButton|] children="chidlren" />; +//// let opt = <[|MainButton|] onClick={()=>{}} />; +//// let opt = <[|MainButton|] onClick={()=>{}} ignore-prop />; +//// let opt = <[|MainButton|] goTo="goTo" />; +//// let opt = <[|MainButton|] wrong />; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxFindAllReferences9.ts b/tests/cases/fourslash/tsxFindAllReferences9.ts new file mode 100644 index 0000000000000..5ac6ad344d8c3 --- /dev/null +++ b/tests/cases/fourslash/tsxFindAllReferences9.ts @@ -0,0 +1,34 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// [|goTo|]: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} ignore-prop />; +//// let opt = ; +//// let opt = ; +//// let opt = ; + +verify.rangesReferenceEachOther(); \ No newline at end of file diff --git a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts index 9c54834534d34..a3ca3057908d1 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts @@ -13,8 +13,10 @@ //// } //// var x = ; //// var y = ; +//// var z = ; verify.goToDefinition({ c: "ct", - p: "pt" + p: "pt", + w: "ct" }); diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts new file mode 100644 index 0000000000000..d715dc5b20445 --- /dev/null +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction1.ts @@ -0,0 +1,31 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// /*pt1*/propx: number +//// propString: "hell" +//// /*pt2*/optional?: boolean +//// } +//// /*opt*/declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; +//// let opt1 = ; +//// let opt2 = ; +//// let opt3 = ; + +verify.goToDefinition({ + one: "opt", + two: "opt", + three: "opt", + four: "opt", + p1: "pt1", + p2: "pt2" +}); diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts new file mode 100644 index 0000000000000..77eb08648289f --- /dev/null +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts @@ -0,0 +1,40 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// /*firstSource*/declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// /*secondSource*/declare function MainButton(linkProps: LinkProps): JSX.Element; +//// /*thirdSource*/declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt =
      ; +//// let opt =
      ; +//// let opt =
      {}} />; +//// let opt =
      {}} ignore-prop />; +//// let opt =
      ; +//// let opt =
      ; + +verify.goToDefinition({ + firstTarget: "firstSource", + secondTarget: "firstSource", + thirdTarget: "firstSource", + fourthTarget: "firstSource", + fivethTarget: "secondSource", + sixthTarget: "firstSource" +}); diff --git a/tests/cases/fourslash/tsxQuickInfo3.ts b/tests/cases/fourslash/tsxQuickInfo3.ts new file mode 100644 index 0000000000000..614ffa878ef09 --- /dev/null +++ b/tests/cases/fourslash/tsxQuickInfo3.ts @@ -0,0 +1,30 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// interface OptionProp { +//// propx: 2 +//// } + +//// class Opt extends React.Component { +//// render() { +//// return
      Hello
      ; +//// } +//// } + +//// const obj1: OptionProp = { +//// propx: 2 +//// } + +//// let y1 = ; +//// let y2 = ; +//// let y2 = ; + +verify.quickInfos({ + 1: "class Opt", + 2: "(JSX attribute) propx: number", + 3: "const obj1: OptionProp", + 4: "(JSX attribute) propx: true" +}); diff --git a/tests/cases/fourslash/tsxQuickInfo4.ts b/tests/cases/fourslash/tsxQuickInfo4.ts new file mode 100644 index 0000000000000..d9f566571aafd --- /dev/null +++ b/tests/cases/fourslash/tsxQuickInfo4.ts @@ -0,0 +1,55 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// export interface ClickableProps { +//// children?: string; +//// className?: string; +//// } + +//// export interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } + +//// export interface LinkProps extends ClickableProps { +//// to: string; +//// } + +//// export function MainButton(buttonProps: ButtonProps): JSX.Element; +//// export function MainButton(linkProps: LinkProps): JSX.Element; +//// export function MainButton(props: ButtonProps | LinkProps): JSX.Element { +//// const linkProps = props as LinkProps; +//// if(linkProps.to) { +//// return this._buildMainLink(props); +//// } +//// return this._buildMainButton(props); +//// } + +//// function _buildMainButton({ onClick, children, className }: ButtonProps): JSX.Element { +//// return(); +//// } + +//// declare function buildMainLink({ to, children, className }: LinkProps): JSX.Element; + +//// function buildSomeElement1(): JSX.Element { +//// return ( +//// GO +//// ); +//// } + +//// function buildSomeElement2(): JSX.Element { +//// return ( +//// {}}>GO; +//// ); +//// } +//// let componenet = {}} ext/*5*/ra-prop>GO; + +verify.quickInfos({ + 1: "function MainButton(linkProps: LinkProps): any (+1 overload)", + 2: "(JSX attribute) to: string", + 3: "function MainButton(buttonProps: ButtonProps): any (+1 overload)", + 4: "(JSX attribute) onClick: () => void", + 5: "(JSX attribute) extra-prop: true" +}); diff --git a/tests/cases/fourslash/tsxQuickInfo5.ts b/tests/cases/fourslash/tsxQuickInfo5.ts new file mode 100644 index 0000000000000..cbdecb67da717 --- /dev/null +++ b/tests/cases/fourslash/tsxQuickInfo5.ts @@ -0,0 +1,18 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare function ComponentWithTwoAttributes(l: {key1: K, value: V}): JSX.Element; + +//// function Baz(key1: T, value: U) { +//// let a0 = +//// let a1 = +//// } + +verify.quickInfos({ + 1: "function ComponentWithTwoAttributes(l: {\n key1: T;\n value: U;\n}): any", + 2: "(JSX attribute) key1: T", + 3: "(JSX attribute) value: U", +}); diff --git a/tests/cases/fourslash/tsxQuickInfo6.ts b/tests/cases/fourslash/tsxQuickInfo6.ts new file mode 100644 index 0000000000000..e121e52c0aac7 --- /dev/null +++ b/tests/cases/fourslash/tsxQuickInfo6.ts @@ -0,0 +1,19 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare function ComponentSpecific(l: {prop: U}): JSX.Element; +//// declare function ComponentSpecific1(l: {prop: U, "ignore-prop": number}): JSX.Element; + +//// function Bar(arg: T) { +//// let a1 = ; // U is number +//// let a2 = ; // U is number +//// let a3 = ; // U is "hello" +//// } + +verify.quickInfos({ + 1: "function ComponentSpecific<{}>(l: {\n prop: {};\n}): any", + 2: "function ComponentSpecific<{}>(l: {\n prop: {};\n}): any" +}); diff --git a/tests/cases/fourslash/tsxQuickInfo7.ts b/tests/cases/fourslash/tsxQuickInfo7.ts new file mode 100644 index 0000000000000..ca90d83d71953 --- /dev/null +++ b/tests/cases/fourslash/tsxQuickInfo7.ts @@ -0,0 +1,29 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare function OverloadComponent(): JSX.Element; +//// declare function OverloadComponent(attr: {b: U, a?: string, "ignore-prop": boolean}): JSX.Element; +//// declare function OverloadComponent(attr: {b: U, a: T}): JSX.Element; + +//// function Baz(arg1: T, arg2: U) { +//// let a0 = ; +//// let a1 = ; +//// let a2 = ; +//// let a3 = ; +//// let a4 = ; +//// let a5 = ; +//// let a6 = ; +//// } + +verify.quickInfos({ + 1: "function OverloadComponent(): any (+2 overloads)", + 2: "function OverloadComponent(): any (+2 overloads)", + 3: "function OverloadComponent(): any (+2 overloads)", + 4: "function OverloadComponent(): any (+2 overloads)", + 5: "function OverloadComponent(): any (+2 overloads)", + 6: "function OverloadComponent(): any (+2 overloads)", + 7: "function OverloadComponent(): any (+2 overloads)" +}); diff --git a/tests/cases/fourslash/tsxRename10.ts b/tests/cases/fourslash/tsxRename10.ts new file mode 100644 index 0000000000000..091f5aa976fe4 --- /dev/null +++ b/tests/cases/fourslash/tsxRename10.ts @@ -0,0 +1,40 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// [|goTo|]: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} ignore-prop />; +//// let opt = ; +//// let opt = ; +//// let opt = ; + + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename11.ts b/tests/cases/fourslash/tsxRename11.ts new file mode 100644 index 0000000000000..97933dd0cc9b2 --- /dev/null +++ b/tests/cases/fourslash/tsxRename11.ts @@ -0,0 +1,39 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// [|onClick|](event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} ignore-prop />; +//// let opt = ; +//// let opt = ; + + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename12.ts b/tests/cases/fourslash/tsxRename12.ts new file mode 100644 index 0000000000000..30e6b506f4d71 --- /dev/null +++ b/tests/cases/fourslash/tsxRename12.ts @@ -0,0 +1,39 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} ignore-prop />; +//// let opt = ; +//// let opt = ; + + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename13.ts b/tests/cases/fourslash/tsxRename13.ts new file mode 100644 index 0000000000000..02d0fb1b3dd2a --- /dev/null +++ b/tests/cases/fourslash/tsxRename13.ts @@ -0,0 +1,39 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function MainButton(buttonProps: ButtonProps): JSX.Element; +//// declare function MainButton(linkProps: LinkProps): JSX.Element; +//// declare function MainButton(props: ButtonProps | LinkProps): JSX.Element; +//// let opt = ; +//// let opt = ; +//// let opt = {}} />; +//// let opt = {}} [|ignore-prop|] />; +//// let opt = ; +//// let opt = ; + + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename6.ts b/tests/cases/fourslash/tsxRename6.ts new file mode 100644 index 0000000000000..59bc3f480099c --- /dev/null +++ b/tests/cases/fourslash/tsxRename6.ts @@ -0,0 +1,30 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// propx: number +//// propString: string +//// optional?: boolean +//// } +//// declare function [|Opt|](attributes: OptionPropBag): JSX.Element; +//// let opt = <[|Opt|] />; +//// let opt1 = <[|Opt|] propx={100} propString />; +//// let opt2 = <[|Opt|] propx={100} optional/>; +//// let opt3 = <[|Opt|] wrong />; +//// let opt4 = <[|Opt|] propx={100} propString="hi" />; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename7.ts b/tests/cases/fourslash/tsxRename7.ts new file mode 100644 index 0000000000000..b5d05e49bd36b --- /dev/null +++ b/tests/cases/fourslash/tsxRename7.ts @@ -0,0 +1,29 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// [|propx|]: number +//// propString: string +//// optional?: boolean +//// } +//// declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; +//// let opt1 = ; +//// let opt2 = ; +//// let opt3 = ; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename8.ts b/tests/cases/fourslash/tsxRename8.ts new file mode 100644 index 0000000000000..48bbff0d88e19 --- /dev/null +++ b/tests/cases/fourslash/tsxRename8.ts @@ -0,0 +1,31 @@ +/// +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface OptionPropBag { +//// propx: number +//// propString: string +//// optional?: boolean +//// } +//// declare function Opt(attributes: OptionPropBag): JSX.Element; +//// let opt = ; +//// let opt1 = ; +//// let opt2 = ; +//// let opt3 = ; +//// let opt4 = ; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxRename9.ts b/tests/cases/fourslash/tsxRename9.ts new file mode 100644 index 0000000000000..4d132f5eac9d6 --- /dev/null +++ b/tests/cases/fourslash/tsxRename9.ts @@ -0,0 +1,38 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true + +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// interface ClickableProps { +//// children?: string; +//// className?: string; +//// } +//// interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } +//// interface LinkProps extends ClickableProps { +//// goTo: string; +//// } +//// declare function [|MainButton|](buttonProps: ButtonProps): JSX.Element; +//// declare function [|MainButton|](linkProps: LinkProps): JSX.Element; +//// declare function [|MainButton|](props: ButtonProps | LinkProps): JSX.Element; +//// let opt = <[|MainButton|] />; +//// let opt = <[|MainButton|] children="chidlren" />; +//// let opt = <[|MainButton|] onClick={()=>{}} />; +//// let opt = <[|MainButton|] onClick={()=>{}} ignore-prop />; +//// let opt = <[|MainButton|] goTo="goTo" />; +//// let opt = <[|MainButton|] wrong />; + +let ranges = test.ranges(); +verify.assertHasRanges(ranges); +for (let range of ranges) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/tsxSignatureHelp1.ts b/tests/cases/fourslash/tsxSignatureHelp1.ts new file mode 100644 index 0000000000000..a0fd59d11ecda --- /dev/null +++ b/tests/cases/fourslash/tsxSignatureHelp1.ts @@ -0,0 +1,35 @@ +/// + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +//// import React = require('react'); +//// export interface ClickableProps { +//// children?: string; +//// className?: string; +//// } + +//// export interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } + +//// function _buildMainButton({ onClick, children, className }: ButtonProps): JSX.Element { +//// return(); +//// } + +//// export function MainButton(props: ButtonProps): JSX.Element { +//// return this._buildMainButton(props); +//// } +//// let e1 = + +//@Filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +//// import React = require('react'); +//// export interface ClickableProps { +//// children?: string; +//// className?: string; +//// } + +//// export interface ButtonProps extends ClickableProps { +//// onClick(event?: React.MouseEvent): void; +//// } + +//// export interface LinkProps extends ClickableProps { +//// goTo(where: "home" | "contact"): void; +//// } + +//// function _buildMainButton({ onClick, children, className }: ButtonProps): JSX.Element { +//// return(); +//// } + +//// export function MainButton(buttonProps: ButtonProps): JSX.Element; +//// export function MainButton(linkProps: LinkProps): JSX.Element; +//// export function MainButton(props: ButtonProps | LinkProps): JSX.Element { +//// return this._buildMainButton(props); +//// } +//// let e1 = Date: Tue, 8 Nov 2016 11:07:45 -0800 Subject: [PATCH 15/25] Fix linting error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 98c5837606982..66135d13aab1a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11117,7 +11117,7 @@ namespace ts { function getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined { const attributes = openingLikeElement.attributes; let attributesTable = createMap(); - let spread: Type = emptyObjectType + let spread: Type = emptyObjectType; let attributesArray: Symbol[] = []; for (const attributeDecl of attributes.properties) { const member = attributeDecl.symbol; From 13ca860cdc467d3b9b4d1a6e9367da4e69ac6a16 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Nov 2016 11:19:26 -0800 Subject: [PATCH 16/25] Address comment: call getContextualType instead of accessing contextualType property directly --- src/compiler/checker.ts | 26 +++++++------------ src/compiler/types.ts | 3 +-- ...StringLiteralsInJsxAttributes02.errors.txt | 8 +++--- ...elessFunctionComponentOverload5.errors.txt | 4 +-- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 66135d13aab1a..cccf3fd45ced0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7013,7 +7013,7 @@ namespace ts { return true; } else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) { - // For JSXAttributes, if the attribute has hyphenated name considered the attribute to be known + // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. return true; } } @@ -10527,27 +10527,19 @@ namespace ts { function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give JSXAttributes a contextual type - // which is a type of the parameter of the signature we are trying out. This is not the case if it is a statefull Jsx (i.e ReactComponenet class) + // which is a type of the parameter of the signature we are trying out. This is not the case if it is a stateful JSX (i.e ReactComponenet class) // So if that is the case, just return the type of the JsxAttribute in such contextual type with out going into resolving of the JsxOpeningLikeElement again - if ((attribute.parent).contextualType) { - return isJsxAttribute(attribute) ? getTypeOfPropertyOfType((attribute.parent).contextualType, attribute.name.text) : undefined; - } - - const kind = attribute.kind; - const jsxElement = attribute.parent.parent as JsxOpeningLikeElement; - const attrsType = getAttributesTypeFromJsxOpeningLikeElement(jsxElement); + const attributesType = getContextualType(attribute.parent) || getAttributesTypeFromJsxOpeningLikeElement(attribute.parent.parent); - if (kind === SyntaxKind.JsxAttribute) { - if (!attrsType || isTypeAny(attrsType)) { + if (isJsxAttribute(attribute)) { + if (!attributesType || isTypeAny(attributesType)) { return undefined; } - return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text); + return getTypeOfPropertyOfType(attributesType, (attribute as JsxAttribute).name.text); } - else if (kind === SyntaxKind.JsxSpreadAttribute) { - return attrsType; + else { + return attributesType; } - - Debug.fail(`Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[${kind}]`); } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily @@ -11228,7 +11220,7 @@ namespace ts { let sourceAttributesType = anyType as Type; let isSourceAttributesTypeEmpty = true; if (symbolArray) { - // Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type + // Filter out any hyphenated names as those do not play any role in type-checking unless there are corresponding properties in the target type const symbolTable = createMap(); forEach(symbolArray, (attr) => { if (isUnhyphenatedJsxName(attr.name) || getPropertyOfType(targetAttributesType, attr.name)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d0ef8ab714fde..68fff1395a048 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1427,14 +1427,13 @@ namespace ts { attributes: JsxAttributes; } - // @kind(SyntaxKind.JsxAttribute) export interface JsxAttribute extends ObjectLiteralElement { + kind: SyntaxKind.JsxAttribute; name: Identifier; /// JSX attribute initializers are optional; is sugar for initializer?: StringLiteral | JsxExpression; } - // @kind(SyntaxKind.JsxSpreadAttribute) export interface JsxSpreadAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxSpreadAttribute; expression: Expression; diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt index 9b6371a1df8be..31f06c48b62cc 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,24): error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,24): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,24): error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. @@ -6,7 +6,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,24): err Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(31,24): error TS2322: Type '{ goTo: "home"; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(34,25): error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(34,25): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. @@ -42,7 +42,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): err const b0 = {console.log(k)}}} extra />; // k has type any ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. const b2 = {console.log(k)}} extra />; // k has type "left" | "right" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -60,7 +60,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): err export function NoOverload(buttonProps: ButtonProps): JSX.Element { return undefined } const c1 = {console.log(k)}}} extra />; // k has type any ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. +!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. export function NoOverload1(linkProps: LinkProps): JSX.Element { return undefined } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index b3d954baa841a..bd04bc1fb40dd 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -4,7 +4,7 @@ tests/cases/conformance/jsx/file.tsx(50,24): error TS2322: Type '{ to: string; o Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. tests/cases/conformance/jsx/file.tsx(51,24): error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. -tests/cases/conformance/jsx/file.tsx(52,24): error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +tests/cases/conformance/jsx/file.tsx(52,24): error TS2322: Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. tests/cases/conformance/jsx/file.tsx(54,24): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & HyphenProps'. Type '{}' is not assignable to type 'HyphenProps'. @@ -84,7 +84,7 @@ tests/cases/conformance/jsx/file.tsx(57,24): error TS2322: Type '{ data-format: !!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. const b3 = {}}} />; // extra property ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. !!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. const b4 = ; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed const b5 = ; // Spread doesn't retain method declaration From 7a95f39f49a7e06f53e19a245f2da7b93bce7fb7 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Nov 2016 15:10:44 -0800 Subject: [PATCH 17/25] Address comment: stop widen type when checking for spread any; Address comment: using ternary operator, fix comments --- src/compiler/checker.ts | 104 +++++++++--------- .../tsxStatelessFunctionComponentOverload2.js | 4 +- ...tatelessFunctionComponentOverload2.symbols | 3 +- ...xStatelessFunctionComponentOverload2.types | 5 +- .../tsxStatelessFunctionComponentOverload3.js | 4 +- ...tatelessFunctionComponentOverload3.symbols | 3 +- ...xStatelessFunctionComponentOverload3.types | 11 +- ...elessFunctionComponentOverload4.errors.txt | 2 +- .../tsxStatelessFunctionComponentOverload4.js | 4 +- ...elessFunctionComponentOverload5.errors.txt | 2 +- .../tsxStatelessFunctionComponentOverload5.js | 4 +- .../tsxStatelessFunctionComponentOverload6.js | 4 +- ...tatelessFunctionComponentOverload6.symbols | 3 +- ...xStatelessFunctionComponentOverload6.types | 7 +- ...tsxStatelessFunctionComponentOverload2.tsx | 2 +- ...tsxStatelessFunctionComponentOverload3.tsx | 2 +- ...tsxStatelessFunctionComponentOverload4.tsx | 2 +- ...tsxStatelessFunctionComponentOverload5.tsx | 2 +- ...tsxStatelessFunctionComponentOverload6.tsx | 2 +- 19 files changed, 81 insertions(+), 89 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cccf3fd45ced0..7253a01a0ea12 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11106,7 +11106,7 @@ namespace ts { * @param openingLikeElement a Jsx opening-like element * @return a symbol table resulted from resolving "attributes" property or undefined if any of the attribute resolved to any or there is no attributes. */ - function getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined { + function getJsxAttributeSymbolsFromJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined { const attributes = openingLikeElement.attributes; let attributesTable = createMap(); let spread: Type = emptyObjectType; @@ -11114,14 +11114,9 @@ namespace ts { for (const attributeDecl of attributes.properties) { const member = attributeDecl.symbol; if (isJsxAttribute(attributeDecl)) { - let exprType: Type; - if (attributeDecl.initializer) { - exprType = checkExpression(attributeDecl.initializer); - } - else { - // is sugar for - exprType = trueType; - } + const exprType = attributeDecl.initializer ? + checkExpression(attributeDecl.initializer) : + trueType; // is sugar for const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); attributeSymbol.declarations = member.declarations; @@ -11142,12 +11137,11 @@ namespace ts { attributesTable = createMap(); } const exprType = checkExpression(attributeDecl.expression); - const widenExprType = getWidenedType(exprType); - if (!(widenExprType.flags & (TypeFlags.Object | TypeFlags.Any))) { + if (!(exprType.flags & (TypeFlags.Object | TypeFlags.Any))) { error(attributeDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return undefined; } - if (isTypeAny(widenExprType)) { + if (isTypeAny(exprType)) { return undefined; } spread = getSpreadType(spread, exprType, /*isFromObjectLiteral*/ false); @@ -11168,11 +11162,11 @@ namespace ts { /** * Create anonymous type from given attributes symbol table. - * @param jsxAttributesSymb a JsxAttributes node containing attributes in attributesTable + * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable * @param attributesTable a symbol table of attributes property */ - function createJsxAttributesType(jsxAttributesSymb: Symbol, attributesTable: Map) { - const result = createAnonymousType(jsxAttributesSymb, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + 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; result.objectFlags |= ObjectFlags.ObjectLiteral; @@ -11182,10 +11176,10 @@ namespace ts { /** * Check JSXAttributes. This function is used when we are trying to figure out call signature for JSX opening-like element. * In "checkApplicableSignatureForJsxOpeningLikeElement", we get type of arguments by checking the JSX opening-like element attributes property with contextual type. - * @param node a JSXAttributes to be resolved of its typea + * @param node a JSXAttributes to be resolved of its type */ function checkJsxAttributes(node: JsxAttributes) { - const symbolArray = getJsxAttributesSymbolArrayFromAttributesProperty(node.parent as JsxOpeningLikeElement); + const symbolArray = getJsxAttributeSymbolsFromJsxOpeningLikeElement(node.parent as JsxOpeningLikeElement); let argAttributesType = anyType as Type; if (symbolArray) { const symbolTable = createMap(); @@ -11203,17 +11197,13 @@ namespace ts { * Check assignablity between given attributes property, "attributes" and the target attributes resulted from resolving tag-name * @param openingLikeElement an opening-like JSX element to check its JSXAttributes */ - function checkJSXAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) { - let targetAttributesType: Type; - // targetAttributesType is a type of an attributes from resolving tagnmae of an opening-like JSX element. - if (isJsxIntrinsicIdentifier(openingLikeElement.tagName)) { - targetAttributesType = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement); - } - else { - targetAttributesType = getCustomJsxElementAttributesType(openingLikeElement); - } + function checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) { + // targetAttributesType is a type of an attributes from resolving tag-name of an opening-like JSX element. + const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? + getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : + getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false); - const symbolArray = getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement); + const symbolArray = getJsxAttributeSymbolsFromJsxOpeningLikeElement(openingLikeElement); // sourceAttributesType is a type of an attributes properties. // i.e
      // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType. @@ -11368,7 +11358,7 @@ namespace ts { // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type if (jsxElementType) { // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. - const callSignature = getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); + const callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); const callReturnType = callSignature && getReturnTypeOfSignature(callSignature); let paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); if (callReturnType && isTypeAssignableTo(callReturnType, jsxElementType)) { @@ -11401,9 +11391,9 @@ namespace ts { if (jsxElementType) { // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. const candidatesOutArray: Signature[] = []; - getResolvedJSXStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray); + getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray); let result: Type; - let defaultResult: Type; + let allMatchingAttributesType: Type; for (const candidate of candidatesOutArray) { const callReturnType = getReturnTypeOfSignature(candidate); const paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); @@ -11420,13 +11410,13 @@ namespace ts { if (shouldBeCandidate) { result = intersectTypes(result, paramType); } - defaultResult = intersectTypes(defaultResult, paramType); + allMatchingAttributesType = intersectTypes(allMatchingAttributesType, paramType); } } // If we can't find any matching, just return everything. if (!result) { - result = defaultResult; + result = allMatchingAttributesType; } // Intersect in JSX.IntrinsicAttributes if it exists const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); @@ -11442,6 +11432,7 @@ namespace ts { /** * Resolve attributes type of the given node. The function is intended to initially be called from getAttributesTypeFromJsxOpeningLikeElement which already handle JSX-intrinsic-element. * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement + * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature * @param elementType an instance type of the given node * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts) * @return attributes'type if able to resolve the type of node @@ -11463,7 +11454,6 @@ namespace ts { }), /*subtypeReduction*/ true); } - // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type if (elementType.flags & TypeFlags.String) { return anyType; @@ -11493,7 +11483,8 @@ namespace ts { // Get the element instance type (the result of newing or invoking this tag) const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType); - // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type + // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. + // Otherwise get only attributes type from the signature picked by choose-overload logic. const statelessAttributesType = shouldIncludeAllStatelessAttributesType ? tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) : defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType); @@ -11565,9 +11556,10 @@ namespace ts { /** * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name. * The function is intended to be called from a function which has checked that the opening element is an intrinsic element. - * @param node an intrinsic JSX oopening-like element + * @param node an intrinsic JSX opening-like element */ function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { + Debug.assert(isJsxIntrinsicIdentifier(node.tagName)); const links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { const symbol = getIntrinsicTagSymbol(node); @@ -11589,7 +11581,7 @@ namespace ts { * The function is intended to be called from a function which has handle intrinsic Jsx element already. * @param node a custom Jsx opening-like element */ - function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType = false): Type { + function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type { const links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { const elemClassType = getJsxGlobalElementClassType(); @@ -11598,6 +11590,13 @@ namespace ts { return links.resolvedJsxElementAttributesType; } + /** + * Get all possible attributes type,especially in the case of overload stateless function component, of the given JSX opening-like element. + * This function is called by language service (see: completions-tryGetGlobalSymbols) + * Because in language service, the given JSX opening-like element may be incomplete and therefore, we can't resolve to exact signature if the element + * is a stateless function component so the best thing to do is return all attributes type from all overloads. + * @param node a JSX opening-like element to get attributes type for + */ function getAllAttributesTypeFromJsxOpeningLikeElement(node: JsxOpeningLikeElement): Type { if (isJsxIntrinsicIdentifier(node.tagName)) { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); @@ -11617,7 +11616,7 @@ namespace ts { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); } else { - return getCustomJsxElementAttributesType(node); + return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false); } } @@ -11678,7 +11677,7 @@ namespace ts { } } - checkJSXAttributesAssignableToTagnameAttributes(openingLikeElement); + checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement); } function checkJsxExpression(node: JsxExpression) { @@ -12130,7 +12129,7 @@ namespace ts { if (isJsxOpeningLikeElement(node)) { // For JSX opening-like element, we will ignore regular arity check (which is what is done here). // Instead, the arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement" as we are required to figure out - // all property inside give attributes. + // all property inside the given attributes. return true; } @@ -12348,30 +12347,29 @@ namespace ts { const paramType = getTypeAtPosition(signature, 0); // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true: - // 1. callIsInCompletes + // 1. callIsIncomplete // 2. attributes property has same number of properties as the parameter object type. // 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 argType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined); - const argProperties = getPropertiesOfType(argType); - const paramProperties = getPropertiesOfType(paramType); if (callIsIncomplete) { return true; } - else if (argProperties.length === paramProperties.length && checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { + + const argType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined); + const argProperties = getPropertiesOfType(argType); + const paramProperties = getPropertiesOfType(paramType); + if (argProperties.length === paramProperties.length && checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { return true; } else { - let shouldCheckArgumentAndParameter = true; for (const arg of argProperties) { if (!getPropertyOfType(paramType, arg.name) && isUnhyphenatedJsxName(arg.name)) { - shouldCheckArgumentAndParameter = false; - break; + return false; } } - if (shouldCheckArgumentAndParameter && checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { + if (checkTypeRelatedTo(argType, paramType, relation, /*errorNode*/ undefined, headMessage)) { return true; } } @@ -13280,7 +13278,7 @@ namespace ts { * @param elementType * @param candidatesOutArray */ - function getResolvedJSXStatelessFunctionSignature(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { + function getResolvedJsxStatelessFunctionSignature(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { Debug.assert(!(elementType.flags & TypeFlags.Union)); const links = getNodeLinks(openingLikeElement); // If getResolvedSignature has already been called, we will have cached the resolvedSignature. @@ -13293,7 +13291,7 @@ namespace ts { } links.resolvedSignature = resolvingSignature; - let callSignature = resolvedStateLessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); + let callSignature = resolvedStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); if (!callSignature || callSignature === unknownSignature) { const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call); callSignature = callSignatures[callSignatures.length - 1]; @@ -13315,13 +13313,13 @@ namespace ts { * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions. * otherwise return undefined if tag-name of the opening-like element doesn't have call signatures */ - function resolvedStateLessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { + function resolvedStatelessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { if (elementType.flags & TypeFlags.Union) { const types = (elementType as UnionType).types; let result: Signature; types.map(type => { // This is mainly to fill in all the candidates if there is one. - result = result || resolvedStateLessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); + result = result || resolvedStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); }); return result; @@ -13349,7 +13347,7 @@ namespace ts { return resolveDecorator(node, candidatesOutArray); case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: - return resolvedStateLessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray); + return resolvedStatelessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray); } Debug.fail("Branch in 'resolveSignature' should be unreachable."); } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js index b34b8ff3b5015..c237cfeb696f5 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.js @@ -18,7 +18,7 @@ let obj2 = { "ignore-prop": "hello" } -let defaultObj = undefined; +let defaultObj: any; // OK const c1 = @@ -47,7 +47,7 @@ define(["require", "exports", "react"], function (require, exports, React) { yy: 500, "ignore-prop": "hello" }; - var defaultObj = undefined; + var defaultObj; // OK var c1 = ; var c2 = ; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols index 6a9b975897282..7757cc1f557db 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.symbols @@ -42,9 +42,8 @@ let obj2 = { "ignore-prop": "hello" } -let defaultObj = undefined; +let defaultObj: any; >defaultObj : Symbol(defaultObj, Decl(file.tsx, 19, 3)) ->undefined : Symbol(undefined) // OK const c1 = diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types index 3736f3b999199..a0fc36b6560f6 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload2.types @@ -50,9 +50,8 @@ let obj2 = { >"hello" : "hello" } -let defaultObj = undefined; +let defaultObj: any; >defaultObj : any ->undefined : undefined // OK const c1 = @@ -105,7 +104,7 @@ const c7 = ; // No error. should pick s >c7 : JSX.Element > : JSX.Element >OneThing : { (): JSX.Element; (l: { yy: number; yy1: string; }): JSX.Element; } ->defaultObj : undefined +>defaultObj : any >yy : true >obj : { yy: number; yy1: string; } diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js index 4a810834e0b8d..f50f65a4f59e8 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.js @@ -6,7 +6,7 @@ interface Context { declare function ZeroThingOrTwoThing(): JSX.Element; declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; -let obj2 = undefined; +let obj2: any; // OK const two1 = ; @@ -25,7 +25,7 @@ const three2 = ; const three3 = ; // it is just any so we allow it to pass through //// [file.jsx] -var obj2 = undefined; +var obj2; // OK var two1 = ; var two2 = ; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols index de5aaa25972d5..a9e336bdf694c 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.symbols @@ -21,9 +21,8 @@ declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Cont >JSX : Symbol(JSX, Decl(react.d.ts, 2352, 1)) >Element : Symbol(JSX.Element, Decl(react.d.ts, 2355, 27)) -let obj2 = undefined; +let obj2: any; >obj2 : Symbol(obj2, Decl(file.tsx, 7, 3)) ->undefined : Symbol(undefined) // OK const two1 = ; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types index ce3e5e7abb6b2..b277bf8a5d7c4 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload3.types @@ -21,9 +21,8 @@ declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Cont >JSX : any >Element : JSX.Element -let obj2 = undefined; +let obj2: any; >obj2 : any ->undefined : undefined // OK const two1 = ; @@ -43,7 +42,7 @@ const two3 = ; // it is just any so we allow i >two3 : JSX.Element > : JSX.Element >ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } ->obj2 : undefined +>obj2 : any const two4 = ; // it is just any so we allow it to pass through >two4 : JSX.Element @@ -51,13 +50,13 @@ const two4 = ; // it is just any so >ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } >yy : number >1000 : 1000 ->obj2 : undefined +>obj2 : any const two5 = ; // it is just any so we allow it to pass through >two5 : JSX.Element > : JSX.Element >ZeroThingOrTwoThing : { (): JSX.Element; (l: { yy: number; yy1: string; }, context: Context): JSX.Element; } ->obj2 : undefined +>obj2 : any >yy : number >1000 : 1000 @@ -105,7 +104,7 @@ const three3 = ; // it is just any so we allow >three3 : JSX.Element > : JSX.Element >ThreeThing : { (l: { y1: string; }): JSX.Element; (l: { y2: string; }): JSX.Element; (l: { yy: number; yy1: string; }, context: Context, updater: any): JSX.Element; } ->obj2 : undefined +>obj2 : any >y2 : number >10 : 10 diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt index f43bd414ef8ff..66b376dad61dc 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt @@ -42,7 +42,7 @@ tests/cases/conformance/jsx/file.tsx(34,29): error TS2322: Type '{ y1: "hello"; yy: 10, yy1: "hello" } - let obj2 = undefined; + let obj2: any; // Error const c0 = ; // extra property; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js index f43b4a845d01e..c2d8bd3cf69c9 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js @@ -8,7 +8,7 @@ let obj = { yy: 10, yy1: "hello" } -let obj2 = undefined; +let obj2: any; // Error const c0 = ; // extra property; @@ -42,7 +42,7 @@ define(["require", "exports", "react"], function (require, exports, React) { yy: 10, yy1: "hello" }; - var obj2 = undefined; + var obj2; // Error var c0 = ; // extra property; var c1 = ; // missing property; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index bd04bc1fb40dd..41ad45973fcfa 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -55,7 +55,7 @@ tests/cases/conformance/jsx/file.tsx(57,24): error TS2322: Type '{ data-format: onClick: ()=>{} } - let obj3 = undefined; + let obj3: any; export function MainButton(buttonProps: ButtonProps): JSX.Element; export function MainButton(linkProps: LinkProps): JSX.Element; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js index 21cae8eb39541..a402d20dc766d 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.js @@ -32,7 +32,7 @@ let obj2 = { onClick: ()=>{} } -let obj3 = undefined; +let obj3: any; export function MainButton(buttonProps: ButtonProps): JSX.Element; export function MainButton(linkProps: LinkProps): JSX.Element; @@ -70,7 +70,7 @@ define(["require", "exports", "react"], function (require, exports, React) { var obj2 = { onClick: function () { } }; - var obj3 = undefined; + var obj3; function MainButton(props) { var linkProps = props; if (linkProps.to) { diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js index 071a7d0534788..1ef3be815b41d 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.js @@ -23,7 +23,7 @@ let obj = { children: "hi", to: "boo" } -let obj1 = undefined; +let obj1: any; let obj2 = { onClick: () => {} } @@ -65,7 +65,7 @@ define(["require", "exports", "react"], function (require, exports, React) { children: "hi", to: "boo" }; - var obj1 = undefined; + var obj1; var obj2 = { onClick: function () { } }; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols index 308752e1c217a..d1aa7ccccc32f 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.symbols @@ -47,9 +47,8 @@ let obj = { to: "boo" >to : Symbol(to, Decl(file.tsx, 21, 19)) } -let obj1 = undefined; +let obj1: any; >obj1 : Symbol(obj1, Decl(file.tsx, 24, 3)) ->undefined : Symbol(undefined) let obj2 = { >obj2 : Symbol(obj2, Decl(file.tsx, 25, 3)) diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types index 296619e2051b6..edd79cad10895 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload6.types @@ -50,9 +50,8 @@ let obj = { >to : string >"boo" : "boo" } -let obj1 = undefined; +let obj1: any; >obj1 : any ->undefined : undefined let obj2 = { >obj2 : { onClick: () => void; } @@ -156,13 +155,13 @@ const b4 = ; // any; just pick the first overload >b4 : JSX.Element > : JSX.Element >MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } ->obj1 : undefined +>obj1 : any const b5 = ; // should pick the second overload >b5 : JSX.Element > : JSX.Element >MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } ->obj1 : undefined +>obj1 : any >to : string const b6 = ; diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx index fe2a3eb747772..53f21b8edac65 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx @@ -22,7 +22,7 @@ let obj2 = { "ignore-prop": "hello" } -let defaultObj = undefined; +let defaultObj: any; // OK const c1 = diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx index 5a21bcfe73675..e4e8fe9f0964f 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx @@ -10,7 +10,7 @@ interface Context { declare function ZeroThingOrTwoThing(): JSX.Element; declare function ZeroThingOrTwoThing(l: {yy: number, yy1: string}, context: Context): JSX.Element; -let obj2 = undefined; +let obj2: any; // OK const two1 = ; diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx index d94c7a5531c48..377878931b818 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx @@ -12,7 +12,7 @@ let obj = { yy: 10, yy1: "hello" } -let obj2 = undefined; +let obj2: any; // Error const c0 = ; // extra property; diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx index 8821d0adccec3..18b0790b2fd88 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload5.tsx @@ -36,7 +36,7 @@ let obj2 = { onClick: ()=>{} } -let obj3 = undefined; +let obj3: any; export function MainButton(buttonProps: ButtonProps): JSX.Element; export function MainButton(linkProps: LinkProps): JSX.Element; diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx index 2bd372eaa0d44..6b88a1088eac6 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx @@ -27,7 +27,7 @@ let obj = { children: "hi", to: "boo" } -let obj1 = undefined; +let obj1: any; let obj2 = { onClick: () => {} } From eff392eaf62e1da88fabcdc7187acb0e800a4f61 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Nov 2016 17:24:36 -0800 Subject: [PATCH 18/25] Refactor getJsxAttributeSymbolsFromJsxOpeningLikeElement to createJsxAttributesTypeFromAttributesProperty --- src/compiler/checker.ts | 85 +++++++++---------- .../tsxElementResolution12.errors.txt | 10 ++- .../reference/tsxElementResolution12.js | 6 ++ .../jsx/tsxElementResolution12.tsx | 3 + 4 files changed, 57 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7253a01a0ea12..c2949ea07fa0f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11102,11 +11102,11 @@ namespace ts { } /** - * Get attributes symbol of the given Jsx opening-like element. The result is from resolving "attributes" property of the opening-like element. + * Get attributes type of the given Jsx opening-like element. The result is from resolving "attributes" property of the opening-like element. * @param openingLikeElement a Jsx opening-like element - * @return a symbol table resulted from resolving "attributes" property or undefined if any of the attribute resolved to any or there is no attributes. + * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property. */ - function getJsxAttributeSymbolsFromJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined { + function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?:(symbol: Symbol)=>boolean) { const attributes = openingLikeElement.attributes; let attributesTable = createMap(); let spread: Type = emptyObjectType; @@ -11139,10 +11139,10 @@ namespace ts { const exprType = checkExpression(attributeDecl.expression); if (!(exprType.flags & (TypeFlags.Object | TypeFlags.Any))) { error(attributeDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); - return undefined; + return anyType; } if (isTypeAny(exprType)) { - return undefined; + return anyType; } spread = getSpreadType(spread, exprType, /*isFromObjectLiteral*/ false); } @@ -11157,38 +11157,38 @@ namespace ts { attributesArray = getPropertiesOfType(spread); } - return attributesArray; - } + attributesTable = createMap(); + if (attributesArray) { + forEach(attributesArray, (attr) => { + if (!filter || (filter && filter(attr))) { + attributesTable[attr.name] = attr; + } + }); + } + return createJsxAttributesType(attributes.symbol, attributesTable); - /** - * Create anonymous type from given attributes symbol table. - * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable - * @param attributesTable a symbol table of attributes property - */ - 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; - result.objectFlags |= ObjectFlags.ObjectLiteral; - return result; + /** + * Create anonymous type from given attributes symbol table. + * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable + * @param attributesTable a symbol table of attributes property + */ + 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; + result.objectFlags |= ObjectFlags.ObjectLiteral; + return result; + } } /** - * Check JSXAttributes. This function is used when we are trying to figure out call signature for JSX opening-like element. - * In "checkApplicableSignatureForJsxOpeningLikeElement", we get type of arguments by checking the JSX opening-like element attributes property with contextual type. + * Check JSXAttributes from "attributes" property. This function is used when we are trying to figure out call signature for JSX opening-like element during chooseOverload + * In "checkApplicableSignatureForJsxOpeningLikeElement", we get type of arguments for potential stateless function by checking + * the JSX opening-like element attributes property with contextual type. * @param node a JSXAttributes to be resolved of its type */ function checkJsxAttributes(node: JsxAttributes) { - const symbolArray = getJsxAttributeSymbolsFromJsxOpeningLikeElement(node.parent as JsxOpeningLikeElement); - let argAttributesType = anyType as Type; - if (symbolArray) { - const symbolTable = createMap(); - forEach(symbolArray, (attr) => { - symbolTable[attr.name] = attr; - }); - argAttributesType = createJsxAttributesType(node.symbol, symbolTable); - } - return argAttributesType; + return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement); } /** @@ -11198,33 +11198,28 @@ namespace ts { * @param openingLikeElement an opening-like JSX element to check its JSXAttributes */ function checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) { + // The function involves following steps: + // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, tagetAttributesType. + // During these steps, we will try to resolve the tag-name as intrinsic name, stateless function, stateful component (in the order) + // 2. Solved Jsx attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element. + // 3. Check if the two are assignable to each other + // targetAttributesType is a type of an attributes from resolving tag-name of an opening-like JSX element. const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false); - const symbolArray = getJsxAttributeSymbolsFromJsxOpeningLikeElement(openingLikeElement); // sourceAttributesType is a type of an attributes properties. // i.e
      // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType. - let sourceAttributesType = anyType as Type; - let isSourceAttributesTypeEmpty = true; - if (symbolArray) { - // Filter out any hyphenated names as those do not play any role in type-checking unless there are corresponding properties in the target type - const symbolTable = createMap(); - forEach(symbolArray, (attr) => { - if (isUnhyphenatedJsxName(attr.name) || getPropertyOfType(targetAttributesType, attr.name)) { - symbolTable[attr.name] = attr; - isSourceAttributesTypeEmpty = false; - } + const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, + (attribute: Symbol) => { + return isUnhyphenatedJsxName(attribute.name) || !!(getPropertyOfType(targetAttributesType, attribute.name)); }); - sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes.symbol, symbolTable); - } - // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type. // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass. - if (targetAttributesType === emptyObjectType && !isTypeAny(sourceAttributesType) && !isSourceAttributesTypeEmpty) { + if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || (sourceAttributesType).properties.length > 0)) { error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName()); } else { diff --git a/tests/baselines/reference/tsxElementResolution12.errors.txt b/tests/baselines/reference/tsxElementResolution12.errors.txt index 5c4c9baf9cd15..e55ec83733262 100644 --- a/tests/baselines/reference/tsxElementResolution12.errors.txt +++ b/tests/baselines/reference/tsxElementResolution12.errors.txt @@ -1,10 +1,11 @@ tests/cases/conformance/jsx/file.tsx(23,1): error TS2607: JSX element class does not support attributes because it does not have a 'pr' property -tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '{ x: "10"; }' is not assignable to type '{ x: number; }'. +tests/cases/conformance/jsx/file.tsx(25,1): error TS2607: JSX element class does not support attributes because it does not have a 'pr' property +tests/cases/conformance/jsx/file.tsx(33,7): error TS2322: Type '{ x: "10"; }' is not assignable to type '{ x: number; }'. Types of property 'x' are incompatible. Type '"10"' is not assignable to type 'number'. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== declare module JSX { interface Element { } interface ElementAttributesProperty { pr: any; } @@ -30,6 +31,11 @@ tests/cases/conformance/jsx/file.tsx(30,7): error TS2322: Type '{ x: "10"; }' is ; // Error ~~~~~~~~~~~~~~~ !!! error TS2607: JSX element class does not support attributes because it does not have a 'pr' property + var attributes: any; + ; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2607: JSX element class does not support attributes because it does not have a 'pr' property + ; // OK interface Obj4type { new(n: string): { x: number; pr: { x: number; } }; diff --git a/tests/baselines/reference/tsxElementResolution12.js b/tests/baselines/reference/tsxElementResolution12.js index b01266aa78984..a4d308fefe6c2 100644 --- a/tests/baselines/reference/tsxElementResolution12.js +++ b/tests/baselines/reference/tsxElementResolution12.js @@ -22,6 +22,9 @@ interface Obj3type { } var Obj3: Obj3type; ; // Error +var attributes: any; +; // Error +; // OK interface Obj4type { new(n: string): { x: number; pr: { x: number; } }; @@ -38,6 +41,9 @@ var Obj2; ; // OK var Obj3; ; // Error +var attributes; +; // Error +; // OK var Obj4; ; // OK ; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution12.tsx b/tests/cases/conformance/jsx/tsxElementResolution12.tsx index a4b47336ef891..daac7cfcbdfce 100644 --- a/tests/cases/conformance/jsx/tsxElementResolution12.tsx +++ b/tests/cases/conformance/jsx/tsxElementResolution12.tsx @@ -23,6 +23,9 @@ interface Obj3type { } var Obj3: Obj3type; ; // Error +var attributes: any; +; // Error +; // OK interface Obj4type { new(n: string): { x: number; pr: { x: number; } }; From 83992eafc13d1c08dae2673a14103cd801a980a0 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Mon, 14 Nov 2016 17:41:25 -0800 Subject: [PATCH 19/25] Address comment: fix spelling mistakes --- src/compiler/checker.ts | 5 ++--- src/services/completions.ts | 8 ++++---- src/services/findAllReferences.ts | 2 +- src/services/signatureHelp.ts | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c2949ea07fa0f..1a63d1e732c6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12848,9 +12848,8 @@ namespace ts { // Do not report any error if we are doing so for stateless function component as such error will be error will be handle in "resolveCustomJsxElementAttributesType". if (isJsxOpeningOrSelfClosingElement) { - // If this is a type resolution session, e.g. Language Service, just return undefined as the language service can decide how to proceed with this failure. - // (see getDefinitionAtPosition which simply get the symbol and return the first declaration of the JSXopeningLikeElement node) - // otherwise, just return the latest signature candidate we try so far so that when we report an error we will get better error message. + // If resolveCall was called by the language service, return undefined to let the language service decide what to do. (see getDefinitionAtPosition) + // Otherwise, return the last candidate we tried so that error reporting can use it. return produceDiagnostics ? candidateForArgumentError : undefined; } diff --git a/src/services/completions.ts b/src/services/completions.ts index da0e0b87e0334..671bdfc37c8b7 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1386,7 +1386,7 @@ namespace ts.Completions { // JsxOpeninLikeElement // attributes: JsxAttributes // properties: NodeArray - return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as JsxOpeningLikeElement; } break; @@ -1399,7 +1399,7 @@ namespace ts.Completions { // JsxOpeninLikeElement // attributes: JsxAttributes // properties: NodeArray - return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as JsxOpeningLikeElement; } break; @@ -1413,7 +1413,7 @@ namespace ts.Completions { // attributes: JsxAttributes // properties: NodeArray // each JsxAttribute can have initializer as JsxExpression - return /*JsxExpression*/parent./*JsxAttribute*/parent./*JsxAttributes*/parent.parent as JsxOpeningLikeElement; + return parent.parent.parent.parent as JsxOpeningLikeElement; } if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) { @@ -1421,7 +1421,7 @@ namespace ts.Completions { // JsxOpeninLikeElement // attributes: JsxAttributes // properties: NodeArray - return /*properties list*/parent./*attributes*/parent.parent as JsxOpeningLikeElement; + return parent.parent.parent as JsxOpeningLikeElement; } break; diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 549be662b81c5..07f0d866bdae6 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1138,7 +1138,7 @@ namespace ts.FindAllReferences { return contextualSymbol; } - // If the reference location is the name of property from object literal destructing pattern + // If the reference location is the name of property from object literal destructuring pattern // Get the property symbol from the object literal's type and look if thats the search symbol // In below eg. get 'property' from type of elems iterating type // for ( { property: p2 } of elems) { } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 43e1bfc595b73..cb75a72753ca4 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -296,7 +296,7 @@ namespace ts.SignatureHelp { // findListItemInfo can return undefined if we are not in parent's argument list // or type argument list. This includes cases where the cursor is: - // - To the right of the closing parenthesize, non-substitution template, or template tail. + // - To the right of the closing parenthesis, non-substitution template, or template tail. // - Between the type arguments and the arguments (greater than token) // - On the target of the call (parent.func) // - On the 'new' keyword in a 'new' expression @@ -358,7 +358,7 @@ namespace ts.SignatureHelp { // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems") // i.e // export function MainButton(props: ButtonProps, context: any): JSX.Element { ... } - // Date: Tue, 15 Nov 2016 12:59:17 -0800 Subject: [PATCH 20/25] Address comment: calling `checkApplicableSignatureForJsxOpeningLikeElement` from inside `checkApplicableSignature` --- src/compiler/checker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1a63d1e732c6e..fb9689725797e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12372,6 +12372,9 @@ namespace ts { } function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { + if (isJsxOpeningLikeElement(node)) { + return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation); + } const thisType = getThisTypeOfSignature(signature); if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType @@ -12951,10 +12954,7 @@ namespace ts { } candidate = getSignatureInstantiation(candidate, typeArgumentTypes); } - if (isJsxOpeningOrSelfClosingElement && !checkApplicableSignatureForJsxOpeningLikeElement(node, candidate, relation)) { - break; - } - else if (!isJsxOpeningOrSelfClosingElement && !checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { + if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { break; } const index = excludeArgument ? indexOf(excludeArgument, true) : -1; From 075a8ce06b34f73e9ce90d8be27f6adc77bb018d Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Nov 2016 12:59:37 -0800 Subject: [PATCH 21/25] Address comment: fix spelling, rename function to be more consistent --- src/compiler/checker.ts | 27 +++++++++++++-------------- src/services/completions.ts | 16 ++++++++-------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb9689725797e..ec2a2d06c2817 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11106,7 +11106,7 @@ namespace ts { * @param openingLikeElement a Jsx opening-like element * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property. */ - function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?:(symbol: Symbol)=>boolean) { + function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean) { const attributes = openingLikeElement.attributes; let attributesTable = createMap(); let spread: Type = emptyObjectType; @@ -12335,12 +12335,6 @@ namespace ts { * @param excludeArgument */ function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map) { - const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; - // Stateless function components can have maximum of three arguments: "props", "context", and "updater". - // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, - // can be specified by users through attributes property. - const paramType = getTypeAtPosition(signature, 0); - // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true: // 1. callIsIncomplete // 2. attributes property has same number of properties as the parameter object type. @@ -12352,6 +12346,11 @@ namespace ts { return true; } + const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; + // Stateless function components can have maximum of three arguments: "props", "context", and "updater". + // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, + // can be specified by users through attributes property. + const paramType = getTypeAtPosition(signature, 0); const argType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined); const argProperties = getPropertiesOfType(argType); const paramProperties = getPropertiesOfType(paramType); @@ -12849,7 +12848,7 @@ namespace ts { return result; } - // Do not report any error if we are doing so for stateless function component as such error will be error will be handle in "resolveCustomJsxElementAttributesType". + // Do not report any error if we are doing so for stateless function component as such error will be handled in "resolveCustomJsxElementAttributesType". if (isJsxOpeningOrSelfClosingElement) { // If resolveCall was called by the language service, return undefined to let the language service decide what to do. (see getDefinitionAtPosition) // Otherwise, return the last candidate we tried so that error reporting can use it. @@ -13285,7 +13284,7 @@ namespace ts { } links.resolvedSignature = resolvingSignature; - let callSignature = resolvedStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); + let callSignature = resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); if (!callSignature || callSignature === unknownSignature) { const callSignatures = elementType && getSignaturesOfType(elementType, SignatureKind.Call); callSignature = callSignatures[callSignatures.length - 1]; @@ -13307,14 +13306,14 @@ namespace ts { * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions. * otherwise return undefined if tag-name of the opening-like element doesn't have call signatures */ - function resolvedStatelessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { + function resolveStatelessJsxOpeningLikeElement(openingLikeElement: JsxOpeningLikeElement, elementType: Type, candidatesOutArray: Signature[]): Signature { if (elementType.flags & TypeFlags.Union) { const types = (elementType as UnionType).types; let result: Signature; - types.map(type => { + for (const type of types) { // This is mainly to fill in all the candidates if there is one. - result = result || resolvedStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); - }); + result = result || resolveStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); + } return result; } @@ -13341,7 +13340,7 @@ namespace ts { return resolveDecorator(node, candidatesOutArray); case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: - return resolvedStatelessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray); + return resolveStatelessJsxOpeningLikeElement(node, checkExpression((node).tagName), candidatesOutArray); } Debug.fail("Branch in 'resolveSignature' should be unreachable."); } diff --git a/src/services/completions.ts b/src/services/completions.ts index 671bdfc37c8b7..42cd5daab828a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1382,8 +1382,8 @@ namespace ts.Completions { return parent; } else if (parent.kind === SyntaxKind.JsxAttribute) { - // Currently we parse JsxOpeninLikeElement as: - // JsxOpeninLikeElement + // Currently we parse JsxOpeningLikeElement as: + // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent as JsxOpeningLikeElement; @@ -1395,8 +1395,8 @@ namespace ts.Completions { // whose parent is a JsxOpeningLikeElement case SyntaxKind.StringLiteral: if (parent && ((parent.kind === SyntaxKind.JsxAttribute) || (parent.kind === SyntaxKind.JsxSpreadAttribute))) { - // Currently we parse JsxOpeninLikeElement as: - // JsxOpeninLikeElement + // Currently we parse JsxOpeningLikeElement as: + // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent as JsxOpeningLikeElement; @@ -1408,8 +1408,8 @@ namespace ts.Completions { if (parent && parent.kind === SyntaxKind.JsxExpression && parent.parent && parent.parent.kind === SyntaxKind.JsxAttribute) { - // Currently we parse JsxOpeninLikeElement as: - // JsxOpeninLikeElement + // Currently we parse JsxOpeningLikeElement as: + // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray // each JsxAttribute can have initializer as JsxExpression @@ -1417,8 +1417,8 @@ namespace ts.Completions { } if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) { - // Currently we parse JsxOpeninLikeElement as: - // JsxOpeninLikeElement + // Currently we parse JsxOpeningLikeElement as: + // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent as JsxOpeningLikeElement; From c1c1e07661368b0a48f5e1b00cfcd992f281522f Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 15 Nov 2016 14:11:21 -0800 Subject: [PATCH 22/25] Address comment: minor fix indentation, fix function name isObjectLiteralPropertyDeclaration => isObjectLiteralElement --- src/services/services.ts | 47 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 5ddae70d05a07..5b594def5be44 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1967,9 +1967,10 @@ namespace ts { } } - function isObjectLiteralPropertyDeclaration(node: Node): node is ObjectLiteralElement { + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { switch (node.kind) { case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxSpreadAttribute: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.MethodDeclaration: @@ -2001,11 +2002,11 @@ namespace ts { case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: if (node.parent.kind === SyntaxKind.ComputedPropertyName) { - return isObjectLiteralPropertyDeclaration(node.parent.parent) ? node.parent.parent : undefined; + return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; } // intentionally fall through case SyntaxKind.Identifier: - return isObjectLiteralPropertyDeclaration(node.parent) && + return isObjectLiteralElement(node.parent) && (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) && (node.parent).name === node ? node.parent as ObjectLiteralElement : undefined; } @@ -2014,27 +2015,27 @@ namespace ts { /* @internal */ export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] { - const objectLiteral = node.parent; - const contextualType = typeChecker.getContextualType(objectLiteral); - const name = getNameFromObjectLiteralElement(node); - if (name && contextualType) { - const result: Symbol[] = []; - const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - - if (contextualType.flags & TypeFlags.Union) { - forEach((contextualType).types, t => { - const symbol = t.getProperty(name); - if (symbol) { - result.push(symbol); - } - }); - } - return result; + const objectLiteral = node.parent; + const contextualType = typeChecker.getContextualType(objectLiteral); + const name = getNameFromObjectLiteralElement(node); + if (name && contextualType) { + const result: Symbol[] = []; + const symbol = contextualType.getProperty(name); + if (symbol) { + result.push(symbol); + } + + if (contextualType.flags & TypeFlags.Union) { + forEach((contextualType).types, t => { + const symbol = t.getProperty(name); + if (symbol) { + result.push(symbol); + } + }); } - return undefined; + return result; + } + return undefined; } function isArgumentOfElementAccessExpression(node: Node) { From 2a62f49831023926b36ee05d27cdfe3d527f802f Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Nov 2016 13:32:39 -0800 Subject: [PATCH 23/25] Address PR: gotoDefinition return the last signature when there is an error in statelss function component --- src/compiler/checker.ts | 7 +++---- .../cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ec2a2d06c2817..f1492c5fadc4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12848,11 +12848,10 @@ namespace ts { return result; } - // Do not report any error if we are doing so for stateless function component as such error will be handled in "resolveCustomJsxElementAttributesType". if (isJsxOpeningOrSelfClosingElement) { - // If resolveCall was called by the language service, return undefined to let the language service decide what to do. (see getDefinitionAtPosition) - // Otherwise, return the last candidate we tried so that error reporting can use it. - return produceDiagnostics ? candidateForArgumentError : undefined; + // If there is not result, just return the last one we try as a candidate. + // We do not report any error here because any error will be handled in "resolveCustomJsxElementAttributesType". + return candidateForArgumentError; } // No signatures were applicable. Now report errors based on the last applicable signature with diff --git a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts index 77eb08648289f..59b2fe80745ea 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionStatelessFunction2.ts @@ -31,10 +31,10 @@ //// let opt =
      ; verify.goToDefinition({ - firstTarget: "firstSource", - secondTarget: "firstSource", + firstTarget: "thirdSource", + secondTarget: "thirdSource", thirdTarget: "firstSource", fourthTarget: "firstSource", fivethTarget: "secondSource", - sixthTarget: "firstSource" + sixthTarget: "thirdSource" }); From 46b8f3231233f01becab2e91a666cc27f9562d54 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 16 Nov 2016 13:44:55 -0800 Subject: [PATCH 24/25] Address PR: convert Foreach to for...of --- src/services/goToDefinition.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 047987cf49b1a..ce4091a59fc86 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -113,10 +113,11 @@ namespace ts.GoToDefinition { if (container) { const contextualType = typeChecker.getContextualType(node.parent.parent as Expression); if (contextualType) { - let result: DefinitionInfo[] = []; - forEach(getPropertySymbolsFromContextualType(typeChecker, container), contextualSymbol => { - result = result.concat(getDefinitionFromSymbol(typeChecker, contextualSymbol, node)); - }); + const result: DefinitionInfo[] = []; + const propertySymbols = getPropertySymbolsFromContextualType(typeChecker, container); + for (const propertySymbol of propertySymbols) { + result.push(...getDefinitionFromSymbol(typeChecker, propertySymbol, node)); + } return result; } } From 6e91aee2a7d1bb686c48c8c17e8fbcccc2e9a5a8 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 6 Dec 2016 15:23:55 -0800 Subject: [PATCH 25/25] Address comment: fix type, inline code, clarify name of variables --- src/compiler/checker.ts | 22 +++------------------- src/compiler/utilities.ts | 16 ++++++++++++++++ src/services/goToDefinition.ts | 11 +++++------ src/services/services.ts | 25 +++++++------------------ 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f1492c5fadc4e..8bd7cbe4a75b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2982,22 +2982,6 @@ namespace ts { return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false); } - function getTextOfPropertyName(name: PropertyName): string { - switch (name.kind) { - case SyntaxKind.Identifier: - return (name).text; - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - return (name).text; - case SyntaxKind.ComputedPropertyName: - if (isStringOrNumericLiteral((name).expression.kind)) { - return ((name).expression).text; - } - } - - return undefined; - } - function isComputedNonLiteralName(name: PropertyName): boolean { return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((name).expression.kind); } @@ -11160,7 +11144,7 @@ namespace ts { attributesTable = createMap(); if (attributesArray) { forEach(attributesArray, (attr) => { - if (!filter || (filter && filter(attr))) { + if (!filter || filter(attr)) { attributesTable[attr.name] = attr; } }); @@ -11199,7 +11183,7 @@ namespace ts { */ function checkJsxAttributesAssignableToTagnameAttributes(openingLikeElement: JsxOpeningLikeElement) { // The function involves following steps: - // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, tagetAttributesType. + // 1. Figure out expected attributes type expected by resolving tag-name of the JSX opening-like element, targetAttributesType. // During these steps, we will try to resolve the tag-name as intrinsic name, stateless function, stateful component (in the order) // 2. Solved Jsx attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element. // 3. Check if the two are assignable to each other @@ -11213,7 +11197,7 @@ namespace ts { // i.e
      // attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". They resolved to be sourceAttributesType. const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, - (attribute: Symbol) => { + attribute => { return isUnhyphenatedJsxName(attribute.name) || !!(getPropertyOfType(targetAttributesType, attribute.name)); }); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7d902ab4e0a87..12beb8f118487 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4623,4 +4623,20 @@ namespace ts { return flags; } + + export function getTextOfPropertyName(name: PropertyName): string { + switch (name.kind) { + case SyntaxKind.Identifier: + return (name).text; + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + return (name).text; + case SyntaxKind.ComputedPropertyName: + if (isStringOrNumericLiteral((name).expression.kind)) { + return ((name).expression).text; + } + } + + return undefined; + } } diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index ce4091a59fc86..e7b4be6896d9b 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -104,17 +104,16 @@ namespace ts.GoToDefinition { // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example // interface Props{ - // /first*/prop1: number + // /*first*/prop1: number // prop2: boolean // } // function Foo(arg: Props) {} // Foo( { pr/*1*/op1: 10, prop2: true }) - const container = getContainingObjectLiteralElement(node); - if (container) { - const contextualType = typeChecker.getContextualType(node.parent.parent as Expression); - if (contextualType) { + const element = getContainingObjectLiteralElement(node); + if (element) { + if (typeChecker.getContextualType(element.parent as Expression)) { const result: DefinitionInfo[] = []; - const propertySymbols = getPropertySymbolsFromContextualType(typeChecker, container); + const propertySymbols = getPropertySymbolsFromContextualType(typeChecker, element); for (const propertySymbol of propertySymbols) { result.push(...getDefinitionFromSymbol(typeChecker, propertySymbol, node)); } diff --git a/src/services/services.ts b/src/services/services.ts index 5b594def5be44..51f9132688709 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1981,18 +1981,6 @@ namespace ts { return false; } - function getNameFromObjectLiteralElement(node: ObjectLiteralElement) { - if (node.name.kind === SyntaxKind.ComputedPropertyName) { - const nameExpression = (node.name).expression; - // treat computed property names where expression is string/numeric literal as just string/numeric literal - if (isStringOrNumericLiteral(nameExpression.kind)) { - return (nameExpression).text; - } - return undefined; - } - return (node.name).text; - } - /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ @@ -2017,14 +2005,10 @@ namespace ts { export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] { const objectLiteral = node.parent; const contextualType = typeChecker.getContextualType(objectLiteral); - const name = getNameFromObjectLiteralElement(node); + const name = getTextOfPropertyName(node.name); if (name && contextualType) { const result: Symbol[] = []; const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - if (contextualType.flags & TypeFlags.Union) { forEach((contextualType).types, t => { const symbol = t.getProperty(name); @@ -2032,8 +2016,13 @@ namespace ts { result.push(symbol); } }); + return result; + } + + if (symbol) { + result.push(symbol); + return result; } - return result; } return undefined; }