From 488397f0ebf8430433cc886d6bb901e84a9529d6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 26 Feb 2018 17:49:26 -0800 Subject: [PATCH] Lookup JSX namespace within factory function --- src/compiler/checker.ts | 169 +++----- src/compiler/types.ts | 2 +- src/services/completions.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...sxFactoryDeclarationsLocalTypes.errors.txt | 129 ++++++ .../inlineJsxFactoryDeclarationsLocalTypes.js | 164 ++++++++ ...neJsxFactoryDeclarationsLocalTypes.symbols | 346 +++++++++++++++ ...lineJsxFactoryDeclarationsLocalTypes.types | 394 ++++++++++++++++++ ...xFactoryLocalTypeGlobalFallback.errors.txt | 51 +++ ...inlineJsxFactoryLocalTypeGlobalFallback.js | 61 +++ ...eJsxFactoryLocalTypeGlobalFallback.symbols | 107 +++++ ...ineJsxFactoryLocalTypeGlobalFallback.types | 110 +++++ .../tsxElementResolution16.errors.txt | 5 +- ...inlineJsxFactoryDeclarationsLocalTypes.tsx | 86 ++++ ...nlineJsxFactoryLocalTypeGlobalFallback.tsx | 44 ++ 16 files changed, 1560 insertions(+), 114 deletions(-) create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types create mode 100644 tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx create mode 100644 tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 63b8d18c451f6..d6aa4760450e7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -417,9 +417,6 @@ namespace ts { let deferredGlobalAsyncIteratorType: GenericType; let deferredGlobalAsyncIterableIteratorType: GenericType; let deferredGlobalTemplateStringsArrayType: ObjectType; - let deferredJsxElementClassType: Type; - let deferredJsxElementType: Type; - let deferredJsxStatelessElementType: Type; let deferredNodes: Node[]; let deferredUnusedIdentifierNodes: Node[]; @@ -545,13 +542,6 @@ namespace ts { let _jsxNamespace: __String; let _jsxFactoryEntity: EntityName; - let _jsxElementPropertiesName: __String; - let _hasComputedJsxElementPropertiesName = false; - let _jsxElementChildrenPropertyName: __String; - let _hasComputedJsxElementChildrenPropertyName = false; - - /** Things we lazy load from the JSX namespace */ - const jsxTypes = createUnderscoreEscapedMap(); const subtypeRelation = createMap(); const assignableRelation = createMap(); @@ -7521,16 +7511,6 @@ namespace ts { return symbol && getTypeOfGlobalSymbol(symbol, arity); } - /** - * Returns a type that is inside a namespace at the global scope, e.g. - * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type - */ - function getExportedTypeFromNamespace(namespace: __String, name: __String): Type { - const namespaceSymbol = getGlobalSymbol(namespace, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); - const typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, SymbolFlags.Type); - return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol); - } - /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ @@ -14345,7 +14325,7 @@ namespace ts { function getContextualTypeForChildJsxExpression(node: JsxElement) { const attributesType = getApparentTypeOfContextualType(node.openingElement.tagName); // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty) - const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(); + const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceForLocation(node)); return attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : undefined; } @@ -14499,18 +14479,10 @@ namespace ts { } const isJs = isInJavaScriptFile(node); - return mapType(valueType, isJs ? getJsxSignaturesParameterTypesJs : getJsxSignaturesParameterTypes); - } - - function getJsxSignaturesParameterTypes(valueType: Type) { - return getJsxSignaturesParameterTypesInternal(valueType, /*isJs*/ false); + return mapType(valueType, t => getJsxSignaturesParameterTypes(t, isJs, node)); } - function getJsxSignaturesParameterTypesJs(valueType: Type) { - return getJsxSignaturesParameterTypesInternal(valueType, /*isJs*/ true); - } - - function getJsxSignaturesParameterTypesInternal(valueType: Type, isJs: boolean) { + function getJsxSignaturesParameterTypes(valueType: Type, isJs: boolean, context: Node) { // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type if (valueType.flags & TypeFlags.String) { return anyType; @@ -14520,7 +14492,7 @@ namespace ts { // For example: // var CustomTag: "h1" = "h1"; // Hello World - const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); + const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, context); if (intrinsicElementsType !== unknownType) { const stringLiteralTypeName = (valueType).value; const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); @@ -14548,24 +14520,24 @@ namespace ts { } } - return getUnionType(map(signatures, ctor ? isJs ? getJsxPropsTypeFromConstructSignatureJs : getJsxPropsTypeFromConstructSignature : getJsxPropsTypeFromCallSignature), UnionReduction.None); + return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromConstructSignature(t, isJs, context) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None); } - function getJsxPropsTypeFromCallSignature(sig: Signature) { + function getJsxPropsTypeFromCallSignature(sig: Signature, context: Node) { let propsType = getTypeOfFirstParameterOfSignature(sig); - const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes); + const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); if (intrinsicAttribs !== unknownType) { propsType = intersectTypes(intrinsicAttribs, propsType); } return propsType; } - function getJsxPropsTypeFromClassType(hostClassType: Type, isJs: boolean) { + function getJsxPropsTypeFromClassType(hostClassType: Type, isJs: boolean, context: Node) { if (isTypeAny(hostClassType)) { return hostClassType; } - const propsName = getJsxElementPropertiesName(); + const propsName = getJsxElementPropertiesName(getJsxNamespaceForLocation(context)); if (propsName === undefined) { // There is no type ElementAttributesProperty, return 'any' return anyType; @@ -14588,7 +14560,7 @@ namespace ts { else { // Normal case -- add in IntrinsicClassElements and IntrinsicElements let apparentAttributesType = attributesType; - const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes); + const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context); if (intrinsicClassAttribs !== unknownType) { const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol); apparentAttributesType = intersectTypes( @@ -14599,7 +14571,7 @@ namespace ts { ); } - const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes); + const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); if (intrinsicAttribs !== unknownType) { apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType); } @@ -14609,20 +14581,12 @@ namespace ts { } } - function getJsxPropsTypeFromConstructSignatureJs(sig: Signature) { - return getJsxPropsTypeFromConstructSignatureInternal(sig, /*isJs*/ true); - } - - function getJsxPropsTypeFromConstructSignature(sig: Signature) { - return getJsxPropsTypeFromConstructSignatureInternal(sig, /*isJs*/ false); - } - - function getJsxPropsTypeFromConstructSignatureInternal(sig: Signature, isJs: boolean) { + function getJsxPropsTypeFromConstructSignature(sig: Signature, isJs: boolean, context: Node) { const hostClassType = getReturnTypeOfSignature(sig); if (hostClassType) { - return getJsxPropsTypeFromClassType(hostClassType, isJs); + return getJsxPropsTypeFromClassType(hostClassType, isJs, context); } - return getJsxPropsTypeFromCallSignature(sig); + return getJsxPropsTypeFromCallSignature(sig, context); } @@ -15077,7 +15041,7 @@ namespace ts { function checkJsxSelfClosingElement(node: JsxSelfClosingElement, checkMode: CheckMode): Type { checkJsxOpeningLikeElementOrOpeningFragment(node, checkMode); - return getJsxGlobalElementType() || anyType; + return getJsxElementTypeAt(node) || anyType; } function checkJsxElement(node: JsxElement, checkMode: CheckMode): Type { @@ -15092,7 +15056,7 @@ namespace ts { checkExpression(node.closingElement.tagName); } - return getJsxGlobalElementType() || anyType; + return getJsxElementTypeAt(node) || anyType; } function checkJsxFragment(node: JsxFragment, checkMode: CheckMode): Type { @@ -15104,7 +15068,7 @@ namespace ts { : Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma); } - return getJsxGlobalElementType() || anyType; + return getJsxElementTypeAt(node) || anyType; } /** @@ -15153,7 +15117,7 @@ namespace ts { let hasSpreadAnyType = false; let typeToIntersect: Type; let explicitlySpecifyChildrenAttribute = false; - const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(); + const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceForLocation(openingLikeElement)); for (const attributeDecl of attributes.properties) { const member = attributeDecl.symbol; @@ -15269,12 +15233,11 @@ namespace ts { return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode); } - function getJsxType(name: __String) { - let jsxType = jsxTypes.get(name); - if (jsxType === undefined) { - jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType); - } - return jsxType; + function getJsxType(name: __String, location: Node) { + const namespace = getJsxNamespaceForLocation(location); + const exports = namespace && getExportsOfSymbol(namespace); + const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type); + return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : unknownType; } /** @@ -15286,7 +15249,7 @@ namespace ts { function getIntrinsicTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol { const links = getNodeLinks(node); if (!links.resolvedSymbol) { - const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); + const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node); if (intrinsicElementsType !== unknownType) { // Property case if (!isIdentifier(node.tagName)) throw Debug.fail(); @@ -15358,6 +15321,19 @@ namespace ts { return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); } + function getJsxNamespaceForLocation(location: Node) { + const namespaceName = getJsxNamespace(location); + const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false); + if (resolvedNamespace) { + const candidate = getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, SymbolFlags.Namespace); + if (candidate) { + return candidate; + } + } + // JSX global fallback + return getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); + } + /** * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer. * Get a single property from that container if existed. Report an error if there are more than one property. @@ -15365,9 +15341,7 @@ namespace ts { * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer * if other string is given or the container doesn't exist, return undefined. */ - function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: __String): __String { - // JSX - const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined); + function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: __String, jsxNamespace: Symbol): __String { // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol] const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, SymbolFlags.Type); // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type] @@ -15397,22 +15371,12 @@ namespace ts { /// non-intrinsic elements' attributes type is 'any'), /// or '' if it has 0 properties (which means every /// non-intrinsic elements' attributes type is the element instance type) - function getJsxElementPropertiesName() { - if (!_hasComputedJsxElementPropertiesName) { - _hasComputedJsxElementPropertiesName = true; - _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer); - } - - return _jsxElementPropertiesName; + function getJsxElementPropertiesName(jsxNamespace: Symbol) { + return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace); } - function getJsxElementChildrenPropertyName(): __String { - if (!_hasComputedJsxElementChildrenPropertyName) { - _hasComputedJsxElementChildrenPropertyName = true; - _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer); - } - - return _jsxElementChildrenPropertyName; + function getJsxElementChildrenPropertyName(jsxNamespace: Symbol): __String { + return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace); } function getApparentTypeOfJsxPropsType(propsType: Type): Type { @@ -15442,7 +15406,7 @@ namespace ts { function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type { Debug.assert(!(elementType.flags & TypeFlags.Union)); if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { - const jsxStatelessElementType = getJsxGlobalStatelessElementType(); + const jsxStatelessElementType = getJsxStatelessElementTypeAt(openingLikeElement); if (jsxStatelessElementType) { // We don't call getResolvedSignature here because we have already resolve the type of JSX Element. const callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); @@ -15452,7 +15416,7 @@ namespace ts { paramType = getApparentTypeOfJsxPropsType(paramType); if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { // Intersect in JSX.IntrinsicAttributes if it exists - const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement); if (intrinsicAttributes !== unknownType) { paramType = intersectTypes(intrinsicAttributes, paramType); } @@ -15478,7 +15442,7 @@ namespace ts { 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 - const jsxStatelessElementType = getJsxGlobalStatelessElementType(); + const jsxStatelessElementType = getJsxStatelessElementTypeAt(openingLikeElement); if (jsxStatelessElementType) { // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. const candidatesOutArray: Signature[] = []; @@ -15511,7 +15475,7 @@ namespace ts { result = allMatchingAttributesType; } // Intersect in JSX.IntrinsicAttributes if it exists - const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); + const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement); if (intrinsicAttributes !== unknownType) { result = intersectTypes(intrinsicAttributes, result); } @@ -15560,7 +15524,7 @@ namespace ts { // For example: // var CustomTag: "h1" = "h1"; // Hello World - const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); + const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, openingLikeElement); if (intrinsicElementsType !== unknownType) { const stringLiteralTypeName = (elementType).value; const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); @@ -15595,7 +15559,7 @@ namespace ts { checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } - return getJsxPropsTypeFromClassType(elemInstanceType, isInJavaScriptFile(openingLikeElement)); + return getJsxPropsTypeFromClassType(elemInstanceType, isInJavaScriptFile(openingLikeElement), openingLikeElement); } /** @@ -15628,7 +15592,7 @@ namespace ts { * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component */ function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type { - return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, checkExpression(node.tagName), getJsxGlobalElementClassType()); + return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, checkExpression(node.tagName), getJsxElementClassTypeAt(node)); } /** @@ -15672,35 +15636,28 @@ namespace ts { return prop || unknownSymbol; } - function getJsxGlobalElementClassType(): Type { - if (!deferredJsxElementClassType) { - deferredJsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass); - } - return deferredJsxElementClassType; + function getJsxElementClassTypeAt(location: Node): Type { + const type = getJsxType(JsxNames.ElementClass, location); + if (type === unknownType) return undefined; + return type; } - function getJsxGlobalElementType(): Type { - if (!deferredJsxElementType) { - deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element); - } - return deferredJsxElementType; + function getJsxElementTypeAt(location: Node): Type { + return getJsxType(JsxNames.Element, location); } - function getJsxGlobalStatelessElementType(): Type { - if (!deferredJsxStatelessElementType) { - const jsxElementType = getJsxGlobalElementType(); - if (jsxElementType) { - deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]); - } + function getJsxStatelessElementTypeAt(location: Node): Type { + const jsxElementType = getJsxElementTypeAt(location); + if (jsxElementType) { + return getUnionType([jsxElementType, nullType]); } - return deferredJsxStatelessElementType; } /** * Returns all the properties of the Jsx.IntrinsicElements interface */ - function getJsxIntrinsicTagNames(): Symbol[] { - const intrinsics = getJsxType(JsxNames.IntrinsicElements); + function getJsxIntrinsicTagNames(location: Node): Symbol[] { + const intrinsics = getJsxType(JsxNames.IntrinsicElements, location); return intrinsics ? getPropertiesOfType(intrinsics) : emptyArray; } @@ -15710,7 +15667,7 @@ namespace ts { error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided); } - if (getJsxGlobalElementType() === undefined) { + if (getJsxElementTypeAt(errorNode) === undefined) { if (noImplicitAny) { error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } @@ -15810,7 +15767,7 @@ namespace ts { // 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) || getPropertiesOfType(sourceAttributesType).length > 0)) { - error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName())); + error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName(getJsxNamespaceForLocation(openingLikeElement)))); } else { // Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6631c66f0eb3c..e4dd66a460aa4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2871,7 +2871,7 @@ namespace ts { /* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[]; getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined; - getJsxIntrinsicTagNames(): Symbol[]; + getJsxIntrinsicTagNames(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; diff --git a/src/services/completions.ts b/src/services/completions.ts index d07c2f494dab4..f2e3df4bc4a8a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -943,7 +943,7 @@ namespace ts.Completions { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { - const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(), "getJsxIntrinsicTagNames() should all be defined"); + const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(location), "getJsxIntrinsicTagNames() should all be defined"); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & (SymbolFlags.Value | SymbolFlags.Alias)))); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9f5ceb1f0cb5e..cd6b7b32f1a13 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1811,7 +1811,7 @@ declare namespace ts { getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined; - getJsxIntrinsicTagNames(): Symbol[]; + getJsxIntrinsicTagNames(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e5fb0b1e1692c..ebfa1f264106f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1811,7 +1811,7 @@ declare namespace ts { getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined; - getJsxIntrinsicTagNames(): Symbol[]; + getJsxIntrinsicTagNames(location: Node): Symbol[]; isOptionalParameter(node: ParameterDeclaration): boolean; getAmbientModules(): Symbol[]; tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined; diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt new file mode 100644 index 0000000000000..438d492d0208a --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt @@ -0,0 +1,129 @@ +tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'. + Property '__predomBrand' is missing in type 'Element'. +tests/cases/conformance/jsx/inline/index.tsx(21,21): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. + Property 'render' is missing in type 'Element'. +tests/cases/conformance/jsx/inline/index.tsx(21,28): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ children?: Element[]; }'. + Types of property 'children' are incompatible. + Type 'dom.JSX.Element[]' is not assignable to type 'predom.JSX.Element[]'. + Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'. +tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. +tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. + Property '__domBrand' is missing in type 'MyClass'. +tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. +tests/cases/conformance/jsx/inline/index.tsx(24,30): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'. + Types of property 'children' are incompatible. + Type 'predom.JSX.Element[]' is not assignable to type 'dom.JSX.Element[]'. + Type 'predom.JSX.Element' is not assignable to type 'dom.JSX.Element'. + Property '__domBrand' is missing in type 'Element'. + + +==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ==== + export namespace dom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } + } + export function dom(): dom.JSX.Element; +==== tests/cases/conformance/jsx/inline/renderer2.d.ts (0 errors) ==== + export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } + } + export function predom(): predom.JSX.Element; +==== tests/cases/conformance/jsx/inline/component.tsx (0 errors) ==== + /** @jsx predom */ + import { predom } from "./renderer2" + + export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

; + + export class MyClass implements predom.JSX.Element { + __predomBrand!: void; + constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {} + render() { + return

+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y} + {...this.props.children} +

; + } + } + export const tree = + + export default + +==== tests/cases/conformance/jsx/inline/index.tsx (7 errors) ==== + /** @jsx dom */ + import { dom } from "./renderer" + import prerendered, {MySFC, MyClass, tree} from "./component"; + let elem = prerendered; + elem = ; // Expect assignability error here + ~~~~ +!!! error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'. +!!! error TS2322: Property '__predomBrand' is missing in type 'Element'. + + const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; + + class DOMClass implements dom.JSX.Element { + __domBrand!: void; + constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {} + render() { + return

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

; + } + } + + // Should work, everything is a DOM element + const _tree = + + // Should fail, no dom elements + const _brokenTree = + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. +!!! error TS2605: Property 'render' is missing in type 'Element'. + ~~~~~~~~~~~ +!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ children?: Element[]; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type 'dom.JSX.Element[]' is not assignable to type 'predom.JSX.Element[]'. +!!! error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'. + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. +!!! error TS2605: Property '__domBrand' is missing in type 'MyClass'. + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. + + // Should fail, nondom isn't allowed as children of dom + const _brokenTree2 = {tree}{tree} + ~~~~~~~~~~~ +!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type 'predom.JSX.Element[]' is not assignable to type 'dom.JSX.Element[]'. +!!! error TS2322: Type 'predom.JSX.Element' is not assignable to type 'dom.JSX.Element'. +!!! error TS2322: Property '__domBrand' is missing in type 'Element'. + \ No newline at end of file diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js new file mode 100644 index 0000000000000..87487b4139da4 --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js @@ -0,0 +1,164 @@ +//// [tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx] //// + +//// [renderer.d.ts] +export namespace dom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function dom(): dom.JSX.Element; +//// [renderer2.d.ts] +export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function predom(): predom.JSX.Element; +//// [component.tsx] +/** @jsx predom */ +import { predom } from "./renderer2" + +export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

; + +export class MyClass implements predom.JSX.Element { + __predomBrand!: void; + constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {} + render() { + return

+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y} + {...this.props.children} +

; + } +} +export const tree = + +export default + +//// [index.tsx] +/** @jsx dom */ +import { dom } from "./renderer" +import prerendered, {MySFC, MyClass, tree} from "./component"; +let elem = prerendered; +elem = ; // Expect assignability error here + +const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; + +class DOMClass implements dom.JSX.Element { + __domBrand!: void; + constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {} + render() { + return

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

; + } +} + +// Should work, everything is a DOM element +const _tree = + +// Should fail, no dom elements +const _brokenTree = + +// Should fail, nondom isn't allowed as children of dom +const _brokenTree2 = {tree}{tree} + + +//// [component.js] +"use strict"; +var _this = this; +exports.__esModule = true; +/** @jsx predom */ +var renderer2_1 = require("./renderer2"); +exports.MySFC = function (props) { return renderer2_1.predom("p", null, + props.x, + " + ", + props.y, + " = ", + props.x + props.y, + _this.props.children); }; +var MyClass = /** @class */ (function () { + function MyClass(props) { + this.props = props; + } + MyClass.prototype.render = function () { + return renderer2_1.predom("p", null, + this.props.x, + " + ", + this.props.y, + " = ", + this.props.x + this.props.y, + this.props.children); + }; + return MyClass; +}()); +exports.MyClass = MyClass; +exports.tree = renderer2_1.predom(exports.MySFC, { x: 1, y: 2 }, + renderer2_1.predom(MyClass, { x: 3, y: 4 }), + renderer2_1.predom(MyClass, { x: 5, y: 6 })); +exports["default"] = renderer2_1.predom("h", null); +//// [index.js] +"use strict"; +exports.__esModule = true; +/** @jsx dom */ +var renderer_1 = require("./renderer"); +var component_1 = require("./component"); +var elem = component_1["default"]; +elem = renderer_1.dom("h", null); // Expect assignability error here +var DOMSFC = function (props) { return renderer_1.dom("p", null, + props.x, + " + ", + props.y, + " = ", + props.x + props.y, + props.children); }; +var DOMClass = /** @class */ (function () { + function DOMClass(props) { + this.props = props; + } + DOMClass.prototype.render = function () { + return renderer_1.dom("p", null, + this.props.x, + " + ", + this.props.y, + " = ", + this.props.x + this.props.y, + this.props.children); + }; + return DOMClass; +}()); +// Should work, everything is a DOM element +var _tree = renderer_1.dom(DOMSFC, { x: 1, y: 2 }, + renderer_1.dom(DOMClass, { x: 3, y: 4 }), + renderer_1.dom(DOMClass, { x: 5, y: 6 })); +// Should fail, no dom elements +var _brokenTree = renderer_1.dom(component_1.MySFC, { x: 1, y: 2 }, + renderer_1.dom(component_1.MyClass, { x: 3, y: 4 }), + renderer_1.dom(component_1.MyClass, { x: 5, y: 6 })); +// Should fail, nondom isn't allowed as children of dom +var _brokenTree2 = renderer_1.dom(DOMSFC, { x: 1, y: 2 }, + component_1.tree, + component_1.tree); diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols new file mode 100644 index 0000000000000..c5b4e795cf668 --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols @@ -0,0 +1,346 @@ +=== tests/cases/conformance/jsx/inline/renderer.d.ts === +export namespace dom { +>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 22)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + + [e: string]: {}; +>e : Symbol(e, Decl(renderer.d.ts, 3, 13)) + } + interface Element { +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + + __domBrand: void; +>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27)) + + props: { +>props : Symbol(Element.props, Decl(renderer.d.ts, 6, 29)) + + children?: Element[]; +>children : Symbol(children, Decl(renderer.d.ts, 7, 20)) +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + + }; + } + interface ElementClass extends Element { +>ElementClass : Symbol(ElementClass, Decl(renderer.d.ts, 10, 9)) +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + + render(): Element; +>render : Symbol(ElementClass.render, Decl(renderer.d.ts, 11, 48)) +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer.d.ts, 13, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(renderer.d.ts, 14, 45)) + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer.d.ts, 14, 59)) +>children : Symbol(ElementChildrenAttribute.children, Decl(renderer.d.ts, 15, 44)) + } +} +export function dom(): dom.JSX.Element; +>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1)) +>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1)) +>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22)) +>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9)) + +=== tests/cases/conformance/jsx/inline/renderer2.d.ts === +export namespace predom { +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(renderer2.d.ts, 0, 25)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + + [e: string]: {}; +>e : Symbol(e, Decl(renderer2.d.ts, 3, 13)) + } + interface Element { +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + + __predomBrand: void; +>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27)) + + props: { +>props : Symbol(Element.props, Decl(renderer2.d.ts, 6, 32)) + + children?: Element[]; +>children : Symbol(children, Decl(renderer2.d.ts, 7, 20)) +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + + }; + } + interface ElementClass extends Element { +>ElementClass : Symbol(ElementClass, Decl(renderer2.d.ts, 10, 9)) +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + + render(): Element; +>render : Symbol(ElementClass.render, Decl(renderer2.d.ts, 11, 48)) +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer2.d.ts, 13, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(renderer2.d.ts, 14, 45)) + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer2.d.ts, 14, 59)) +>children : Symbol(ElementChildrenAttribute.children, Decl(renderer2.d.ts, 15, 44)) + } +} +export function predom(): predom.JSX.Element; +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1)) +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1)) +>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) + +=== tests/cases/conformance/jsx/inline/component.tsx === +/** @jsx predom */ +import { predom } from "./renderer2" +>predom : Symbol(predom, Decl(component.tsx, 1, 8)) + +export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

; +>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12)) +>props : Symbol(props, Decl(component.tsx, 3, 22)) +>x : Symbol(x, Decl(component.tsx, 3, 30)) +>y : Symbol(y, Decl(component.tsx, 3, 40)) +>children : Symbol(children, Decl(component.tsx, 3, 51)) +>predom : Symbol(predom, Decl(component.tsx, 1, 8)) +>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) +>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) +>props.x : Symbol(x, Decl(component.tsx, 3, 30)) +>props : Symbol(props, Decl(component.tsx, 3, 22)) +>x : Symbol(x, Decl(component.tsx, 3, 30)) +>props.y : Symbol(y, Decl(component.tsx, 3, 40)) +>props : Symbol(props, Decl(component.tsx, 3, 22)) +>y : Symbol(y, Decl(component.tsx, 3, 40)) +>props.x : Symbol(x, Decl(component.tsx, 3, 30)) +>props : Symbol(props, Decl(component.tsx, 3, 22)) +>x : Symbol(x, Decl(component.tsx, 3, 30)) +>props.y : Symbol(y, Decl(component.tsx, 3, 40)) +>props : Symbol(props, Decl(component.tsx, 3, 22)) +>y : Symbol(y, Decl(component.tsx, 3, 40)) +>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + +export class MyClass implements predom.JSX.Element { +>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>predom.JSX.Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) +>predom.JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>predom : Symbol(predom, Decl(component.tsx, 1, 8)) +>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) + + __predomBrand!: void; +>__predomBrand : Symbol(MyClass.__predomBrand, Decl(component.tsx, 5, 52)) + + constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {} +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>x : Symbol(x, Decl(component.tsx, 7, 31)) +>y : Symbol(y, Decl(component.tsx, 7, 41)) +>children : Symbol(children, Decl(component.tsx, 7, 52)) +>predom : Symbol(predom, Decl(component.tsx, 1, 8)) +>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) + + render() { +>render : Symbol(MyClass.render, Decl(component.tsx, 7, 89)) + + return

+>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + + {this.props.x} + {this.props.y} = {this.props.x + this.props.y} +>this.props.x : Symbol(x, Decl(component.tsx, 7, 31)) +>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>this : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>x : Symbol(x, Decl(component.tsx, 7, 31)) +>this.props.y : Symbol(y, Decl(component.tsx, 7, 41)) +>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>this : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>y : Symbol(y, Decl(component.tsx, 7, 41)) +>this.props.x : Symbol(x, Decl(component.tsx, 7, 31)) +>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>this : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>x : Symbol(x, Decl(component.tsx, 7, 31)) +>this.props.y : Symbol(y, Decl(component.tsx, 7, 41)) +>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>this : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>y : Symbol(y, Decl(component.tsx, 7, 41)) + + {...this.props.children} +>this.props.children : Symbol(children, Decl(component.tsx, 7, 52)) +>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>this : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16)) +>children : Symbol(children, Decl(component.tsx, 7, 52)) + +

; +>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + } +} +export const tree = +>tree : Symbol(tree, Decl(component.tsx, 15, 12)) +>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12)) +>x : Symbol(x, Decl(component.tsx, 15, 26)) +>y : Symbol(y, Decl(component.tsx, 15, 32)) +>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>x : Symbol(x, Decl(component.tsx, 15, 47)) +>y : Symbol(y, Decl(component.tsx, 15, 53)) +>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164)) +>x : Symbol(x, Decl(component.tsx, 15, 70)) +>y : Symbol(y, Decl(component.tsx, 15, 76)) +>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12)) + +export default +>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) +>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + +=== tests/cases/conformance/jsx/inline/index.tsx === +/** @jsx dom */ +import { dom } from "./renderer" +>dom : Symbol(dom, Decl(index.tsx, 1, 8)) + +import prerendered, {MySFC, MyClass, tree} from "./component"; +>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6)) +>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21)) +>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27)) +>tree : Symbol(tree, Decl(index.tsx, 2, 36)) + +let elem = prerendered; +>elem : Symbol(elem, Decl(index.tsx, 3, 3)) +>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6)) + +elem = ; // Expect assignability error here +>elem : Symbol(elem, Decl(index.tsx, 3, 3)) +>h : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) +>h : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + +const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; +>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>x : Symbol(x, Decl(index.tsx, 6, 24)) +>y : Symbol(y, Decl(index.tsx, 6, 34)) +>children : Symbol(children, Decl(index.tsx, 6, 45)) +>dom : Symbol(dom, Decl(index.tsx, 1, 8)) +>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22)) +>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9)) +>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) +>props.x : Symbol(x, Decl(index.tsx, 6, 24)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>x : Symbol(x, Decl(index.tsx, 6, 24)) +>props.y : Symbol(y, Decl(index.tsx, 6, 34)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>y : Symbol(y, Decl(index.tsx, 6, 34)) +>props.x : Symbol(x, Decl(index.tsx, 6, 24)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>x : Symbol(x, Decl(index.tsx, 6, 24)) +>props.y : Symbol(y, Decl(index.tsx, 6, 34)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>y : Symbol(y, Decl(index.tsx, 6, 34)) +>props.children : Symbol(children, Decl(index.tsx, 6, 45)) +>props : Symbol(props, Decl(index.tsx, 6, 16)) +>children : Symbol(children, Decl(index.tsx, 6, 45)) +>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + +class DOMClass implements dom.JSX.Element { +>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>dom.JSX.Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9)) +>dom.JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22)) +>dom : Symbol(dom, Decl(index.tsx, 1, 8)) +>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22)) +>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9)) + + __domBrand!: void; +>__domBrand : Symbol(DOMClass.__domBrand, Decl(index.tsx, 8, 43)) + + constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {} +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>x : Symbol(x, Decl(index.tsx, 10, 31)) +>y : Symbol(y, Decl(index.tsx, 10, 41)) +>children : Symbol(children, Decl(index.tsx, 10, 52)) +>dom : Symbol(dom, Decl(index.tsx, 1, 8)) +>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22)) +>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9)) + + render() { +>render : Symbol(DOMClass.render, Decl(index.tsx, 10, 86)) + + return

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

; +>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) +>this.props.x : Symbol(x, Decl(index.tsx, 10, 31)) +>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>this : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>x : Symbol(x, Decl(index.tsx, 10, 31)) +>this.props.y : Symbol(y, Decl(index.tsx, 10, 41)) +>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>this : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>y : Symbol(y, Decl(index.tsx, 10, 41)) +>this.props.x : Symbol(x, Decl(index.tsx, 10, 31)) +>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>this : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>x : Symbol(x, Decl(index.tsx, 10, 31)) +>this.props.y : Symbol(y, Decl(index.tsx, 10, 41)) +>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>this : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>y : Symbol(y, Decl(index.tsx, 10, 41)) +>this.props.children : Symbol(children, Decl(index.tsx, 10, 52)) +>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>this : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16)) +>children : Symbol(children, Decl(index.tsx, 10, 52)) +>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + } +} + +// Should work, everything is a DOM element +const _tree = +>_tree : Symbol(_tree, Decl(index.tsx, 17, 5)) +>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5)) +>x : Symbol(x, Decl(index.tsx, 17, 21)) +>y : Symbol(y, Decl(index.tsx, 17, 27)) +>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>x : Symbol(x, Decl(index.tsx, 17, 43)) +>y : Symbol(y, Decl(index.tsx, 17, 49)) +>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147)) +>x : Symbol(x, Decl(index.tsx, 17, 67)) +>y : Symbol(y, Decl(index.tsx, 17, 73)) +>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5)) + +// Should fail, no dom elements +const _brokenTree = +>_brokenTree : Symbol(_brokenTree, Decl(index.tsx, 20, 5)) +>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21)) +>x : Symbol(x, Decl(index.tsx, 20, 26)) +>y : Symbol(y, Decl(index.tsx, 20, 32)) +>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27)) +>x : Symbol(x, Decl(index.tsx, 20, 47)) +>y : Symbol(y, Decl(index.tsx, 20, 53)) +>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27)) +>x : Symbol(x, Decl(index.tsx, 20, 70)) +>y : Symbol(y, Decl(index.tsx, 20, 76)) +>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21)) + +// Should fail, nondom isn't allowed as children of dom +const _brokenTree2 = {tree}{tree} +>_brokenTree2 : Symbol(_brokenTree2, Decl(index.tsx, 23, 5)) +>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5)) +>x : Symbol(x, Decl(index.tsx, 23, 28)) +>y : Symbol(y, Decl(index.tsx, 23, 34)) +>tree : Symbol(tree, Decl(index.tsx, 2, 36)) +>tree : Symbol(tree, Decl(index.tsx, 2, 36)) +>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5)) + diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types new file mode 100644 index 0000000000000..d33da0d6494ce --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types @@ -0,0 +1,394 @@ +=== tests/cases/conformance/jsx/inline/renderer.d.ts === +export namespace dom { +>dom : () => JSX.Element + + namespace JSX { +>JSX : any + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [e: string]: {}; +>e : string + } + interface Element { +>Element : Element + + __domBrand: void; +>__domBrand : void + + props: { +>props : { children?: Element[]; } + + children?: Element[]; +>children : Element[] +>Element : Element + + }; + } + interface ElementClass extends Element { +>ElementClass : ElementClass +>Element : Element + + render(): Element; +>render : () => Element +>Element : Element + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : ElementAttributesProperty +>props : any + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : any + } +} +export function dom(): dom.JSX.Element; +>dom : () => dom.JSX.Element +>dom : any +>JSX : any +>Element : dom.JSX.Element + +=== tests/cases/conformance/jsx/inline/renderer2.d.ts === +export namespace predom { +>predom : () => JSX.Element + + namespace JSX { +>JSX : any + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [e: string]: {}; +>e : string + } + interface Element { +>Element : Element + + __predomBrand: void; +>__predomBrand : void + + props: { +>props : { children?: Element[]; } + + children?: Element[]; +>children : Element[] +>Element : Element + + }; + } + interface ElementClass extends Element { +>ElementClass : ElementClass +>Element : Element + + render(): Element; +>render : () => Element +>Element : Element + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : ElementAttributesProperty +>props : any + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : any + } +} +export function predom(): predom.JSX.Element; +>predom : () => predom.JSX.Element +>predom : any +>JSX : any +>Element : predom.JSX.Element + +=== tests/cases/conformance/jsx/inline/component.tsx === +/** @jsx predom */ +import { predom } from "./renderer2" +>predom : () => predom.JSX.Element + +export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

; +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element +>(props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

: (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>y : number +>children : predom.JSX.Element[] +>predom : any +>JSX : any +>Element : predom.JSX.Element +>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

: predom.JSX.Element +>p : any +>props.x : number +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>props.y : number +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>y : number +>props.x + props.y : number +>props.x : number +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>props.y : number +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>y : number +>this.props.children : any +>this.props : any +>this : any +>props : any +>children : any +>p : any + +export class MyClass implements predom.JSX.Element { +>MyClass : MyClass +>predom.JSX.Element : any +>predom.JSX : any +>predom : () => predom.JSX.Element +>JSX : any +>Element : predom.JSX.Element + + __predomBrand!: void; +>__predomBrand : void + + constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {} +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>y : number +>children : predom.JSX.Element[] +>predom : any +>JSX : any +>Element : predom.JSX.Element + + render() { +>render : () => predom.JSX.Element + + return

+>

{this.props.x} + {this.props.y} = {this.props.x + this.props.y} {...this.props.children}

: predom.JSX.Element +>p : any + + {this.props.x} + {this.props.y} = {this.props.x + this.props.y} +>this.props.x : number +>this.props : { x: number; y: number; children?: predom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>this.props.y : number +>this.props : { x: number; y: number; children?: predom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>y : number +>this.props.x + this.props.y : number +>this.props.x : number +>this.props : { x: number; y: number; children?: predom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>x : number +>this.props.y : number +>this.props : { x: number; y: number; children?: predom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>y : number + + {...this.props.children} +>this.props.children : predom.JSX.Element[] +>this.props : { x: number; y: number; children?: predom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: predom.JSX.Element[]; } +>children : predom.JSX.Element[] + +

; +>p : any + } +} +export const tree = +>tree : predom.JSX.Element +> : predom.JSX.Element +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element +>x : number +>1 : 1 +>y : number +>2 : 2 +> : predom.JSX.Element +>MyClass : typeof MyClass +>x : number +>3 : 3 +>y : number +>4 : 4 +> : predom.JSX.Element +>MyClass : typeof MyClass +>x : number +>5 : 5 +>y : number +>6 : 6 +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element + +export default +> : predom.JSX.Element +>h : any +>h : any + +=== tests/cases/conformance/jsx/inline/index.tsx === +/** @jsx dom */ +import { dom } from "./renderer" +>dom : () => dom.JSX.Element + +import prerendered, {MySFC, MyClass, tree} from "./component"; +>prerendered : predom.JSX.Element +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element +>MyClass : typeof MyClass +>tree : predom.JSX.Element + +let elem = prerendered; +>elem : predom.JSX.Element +>prerendered : predom.JSX.Element + +elem = ; // Expect assignability error here +>elem = : dom.JSX.Element +>elem : predom.JSX.Element +> : dom.JSX.Element +>h : any +>h : any + +const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; +>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element +>(props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

: (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>y : number +>children : dom.JSX.Element[] +>dom : any +>JSX : any +>Element : dom.JSX.Element +>

{props.x} + {props.y} = {props.x + props.y}{props.children}

: dom.JSX.Element +>p : any +>props.x : number +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>props.y : number +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>y : number +>props.x + props.y : number +>props.x : number +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>props.y : number +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>y : number +>props.children : dom.JSX.Element[] +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>children : dom.JSX.Element[] +>p : any + +class DOMClass implements dom.JSX.Element { +>DOMClass : DOMClass +>dom.JSX.Element : any +>dom.JSX : any +>dom : () => dom.JSX.Element +>JSX : any +>Element : dom.JSX.Element + + __domBrand!: void; +>__domBrand : void + + constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {} +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>y : number +>children : dom.JSX.Element[] +>dom : any +>JSX : any +>Element : dom.JSX.Element + + render() { +>render : () => dom.JSX.Element + + return

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

; +>

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

: dom.JSX.Element +>p : any +>this.props.x : number +>this.props : { x: number; y: number; children?: dom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>this.props.y : number +>this.props : { x: number; y: number; children?: dom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>y : number +>this.props.x + this.props.y : number +>this.props.x : number +>this.props : { x: number; y: number; children?: dom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>x : number +>this.props.y : number +>this.props : { x: number; y: number; children?: dom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>y : number +>this.props.children : dom.JSX.Element[] +>this.props : { x: number; y: number; children?: dom.JSX.Element[]; } +>this : this +>props : { x: number; y: number; children?: dom.JSX.Element[]; } +>children : dom.JSX.Element[] +>p : any + } +} + +// Should work, everything is a DOM element +const _tree = +>_tree : dom.JSX.Element +> : dom.JSX.Element +>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element +>x : number +>1 : 1 +>y : number +>2 : 2 +> : dom.JSX.Element +>DOMClass : typeof DOMClass +>x : number +>3 : 3 +>y : number +>4 : 4 +> : dom.JSX.Element +>DOMClass : typeof DOMClass +>x : number +>5 : 5 +>y : number +>6 : 6 +>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element + +// Should fail, no dom elements +const _brokenTree = +>_brokenTree : dom.JSX.Element +> : dom.JSX.Element +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element +>x : number +>1 : 1 +>y : number +>2 : 2 +> : dom.JSX.Element +>MyClass : typeof MyClass +>x : number +>3 : 3 +>y : number +>4 : 4 +> : dom.JSX.Element +>MyClass : typeof MyClass +>x : number +>5 : 5 +>y : number +>6 : 6 +>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element + +// Should fail, nondom isn't allowed as children of dom +const _brokenTree2 = {tree}{tree} +>_brokenTree2 : dom.JSX.Element +>{tree}{tree} : dom.JSX.Element +>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element +>x : number +>1 : 1 +>y : number +>2 : 2 +>tree : predom.JSX.Element +>tree : predom.JSX.Element +>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element + diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt new file mode 100644 index 0000000000000..9d4e4e0a026f5 --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt @@ -0,0 +1,51 @@ +tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2322: Type 'JSX.Element' is not assignable to type 'predom.JSX.Element'. + Property '__predomBrand' is missing in type 'Element'. + + +==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ==== + declare global { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } + } + export function dom(): JSX.Element; +==== tests/cases/conformance/jsx/inline/renderer2.d.ts (0 errors) ==== + export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } + } + export function predom(): predom.JSX.Element; +==== tests/cases/conformance/jsx/inline/component.tsx (0 errors) ==== + /** @jsx predom */ + import { predom } from "./renderer2" + export default + +==== tests/cases/conformance/jsx/inline/index.tsx (1 errors) ==== + /** @jsx dom */ + import { dom } from "./renderer" + import prerendered from "./component"; + let elem = prerendered; + elem = ; // Expect assignability error here + ~~~~ +!!! error TS2322: Type 'JSX.Element' is not assignable to type 'predom.JSX.Element'. +!!! error TS2322: Property '__predomBrand' is missing in type 'Element'. + \ No newline at end of file diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js new file mode 100644 index 0000000000000..4f5123ed67ddf --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js @@ -0,0 +1,61 @@ +//// [tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx] //// + +//// [renderer.d.ts] +declare global { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function dom(): JSX.Element; +//// [renderer2.d.ts] +export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function predom(): predom.JSX.Element; +//// [component.tsx] +/** @jsx predom */ +import { predom } from "./renderer2" +export default + +//// [index.tsx] +/** @jsx dom */ +import { dom } from "./renderer" +import prerendered from "./component"; +let elem = prerendered; +elem = ; // Expect assignability error here + + +//// [component.js] +"use strict"; +exports.__esModule = true; +/** @jsx predom */ +var renderer2_1 = require("./renderer2"); +exports["default"] = renderer2_1.predom("h", null); +//// [index.js] +"use strict"; +exports.__esModule = true; +/** @jsx dom */ +var renderer_1 = require("./renderer"); +var component_1 = require("./component"); +var elem = component_1["default"]; +elem = renderer_1.dom("h", null); // Expect assignability error here diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols new file mode 100644 index 0000000000000..c496201587190 --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols @@ -0,0 +1,107 @@ +=== tests/cases/conformance/jsx/inline/renderer.d.ts === +declare global { +>global : Symbol(global, Decl(renderer.d.ts, 0, 0)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 16)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + + [e: string]: {}; +>e : Symbol(e, Decl(renderer.d.ts, 3, 13)) + } + interface Element { +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + + __domBrand: void; +>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27)) + + children: Element[]; +>children : Symbol(Element.children, Decl(renderer.d.ts, 6, 29)) +>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9)) + + props: {}; +>props : Symbol(Element.props, Decl(renderer.d.ts, 7, 32)) + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer.d.ts, 9, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(renderer.d.ts, 10, 45)) + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer.d.ts, 10, 59)) +>children : Symbol(ElementChildrenAttribute.children, Decl(renderer.d.ts, 11, 44)) + } +} +export function dom(): JSX.Element; +>dom : Symbol(dom, Decl(renderer.d.ts, 13, 1)) +>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 16)) +>Element : Symbol(JSX.Element, Decl(renderer.d.ts, 4, 9)) + +=== tests/cases/conformance/jsx/inline/renderer2.d.ts === +export namespace predom { +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(renderer2.d.ts, 0, 25)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + + [e: string]: {}; +>e : Symbol(e, Decl(renderer2.d.ts, 3, 13)) + } + interface Element { +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + + __predomBrand: void; +>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27)) + + children: Element[]; +>children : Symbol(Element.children, Decl(renderer2.d.ts, 6, 32)) +>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9)) + + props: {}; +>props : Symbol(Element.props, Decl(renderer2.d.ts, 7, 32)) + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer2.d.ts, 9, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(renderer2.d.ts, 10, 45)) + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer2.d.ts, 10, 59)) +>children : Symbol(ElementChildrenAttribute.children, Decl(renderer2.d.ts, 11, 44)) + } +} +export function predom(): predom.JSX.Element; +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1)) +>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1)) +>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25)) +>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9)) + +=== tests/cases/conformance/jsx/inline/component.tsx === +/** @jsx predom */ +import { predom } from "./renderer2" +>predom : Symbol(predom, Decl(component.tsx, 1, 8)) + +export default +>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) +>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19)) + +=== tests/cases/conformance/jsx/inline/index.tsx === +/** @jsx dom */ +import { dom } from "./renderer" +>dom : Symbol(dom, Decl(index.tsx, 1, 8)) + +import prerendered from "./component"; +>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6)) + +let elem = prerendered; +>elem : Symbol(elem, Decl(index.tsx, 3, 3)) +>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6)) + +elem = ; // Expect assignability error here +>elem : Symbol(elem, Decl(index.tsx, 3, 3)) +>h : Symbol(JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) +>h : Symbol(JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19)) + diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types new file mode 100644 index 0000000000000..369341f0f7a13 --- /dev/null +++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types @@ -0,0 +1,110 @@ +=== tests/cases/conformance/jsx/inline/renderer.d.ts === +declare global { +>global : any + + namespace JSX { +>JSX : any + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [e: string]: {}; +>e : string + } + interface Element { +>Element : Element + + __domBrand: void; +>__domBrand : void + + children: Element[]; +>children : Element[] +>Element : Element + + props: {}; +>props : {} + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : ElementAttributesProperty +>props : any + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : any + } +} +export function dom(): JSX.Element; +>dom : () => JSX.Element +>JSX : any +>Element : JSX.Element + +=== tests/cases/conformance/jsx/inline/renderer2.d.ts === +export namespace predom { +>predom : () => JSX.Element + + namespace JSX { +>JSX : any + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [e: string]: {}; +>e : string + } + interface Element { +>Element : Element + + __predomBrand: void; +>__predomBrand : void + + children: Element[]; +>children : Element[] +>Element : Element + + props: {}; +>props : {} + } + interface ElementAttributesProperty { props: any; } +>ElementAttributesProperty : ElementAttributesProperty +>props : any + + interface ElementChildrenAttribute { children: any; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : any + } +} +export function predom(): predom.JSX.Element; +>predom : () => predom.JSX.Element +>predom : any +>JSX : any +>Element : predom.JSX.Element + +=== tests/cases/conformance/jsx/inline/component.tsx === +/** @jsx predom */ +import { predom } from "./renderer2" +>predom : () => predom.JSX.Element + +export default +> : predom.JSX.Element +>h : any +>h : any + +=== tests/cases/conformance/jsx/inline/index.tsx === +/** @jsx dom */ +import { dom } from "./renderer" +>dom : () => JSX.Element + +import prerendered from "./component"; +>prerendered : predom.JSX.Element + +let elem = prerendered; +>elem : predom.JSX.Element +>prerendered : predom.JSX.Element + +elem = ; // Expect assignability error here +>elem = : JSX.Element +>elem : predom.JSX.Element +> : JSX.Element +>h : any +>h : any + diff --git a/tests/baselines/reference/tsxElementResolution16.errors.txt b/tests/baselines/reference/tsxElementResolution16.errors.txt index b68c442c36d66..07b2ec54b44a0 100644 --- a/tests/baselines/reference/tsxElementResolution16.errors.txt +++ b/tests/baselines/reference/tsxElementResolution16.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/jsx/file.tsx(8,1): error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist. tests/cases/conformance/jsx/file.tsx(8,1): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== declare module JSX { } @@ -12,7 +11,5 @@ tests/cases/conformance/jsx/file.tsx(8,1): error TS7026: JSX element implicitly var obj1: Obj1; ; // Error (JSX.Element is implicit any) ~~~~~~~~~~~~~~~ -!!! error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist. - ~~~~~~~~~~~~~~~ !!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. \ No newline at end of file diff --git a/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx b/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx new file mode 100644 index 0000000000000..009abe2e852c8 --- /dev/null +++ b/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx @@ -0,0 +1,86 @@ +// @jsx: react +// @filename: renderer.d.ts +export namespace dom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function dom(): dom.JSX.Element; +// @filename: renderer2.d.ts +export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + props: { + children?: Element[]; + }; + } + interface ElementClass extends Element { + render(): Element; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function predom(): predom.JSX.Element; +// @filename: component.tsx +/** @jsx predom */ +import { predom } from "./renderer2" + +export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{...this.props.children}

; + +export class MyClass implements predom.JSX.Element { + __predomBrand!: void; + constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {} + render() { + return

+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y} + {...this.props.children} +

; + } +} +export const tree = + +export default + +// @filename: index.tsx +/** @jsx dom */ +import { dom } from "./renderer" +import prerendered, {MySFC, MyClass, tree} from "./component"; +let elem = prerendered; +elem = ; // Expect assignability error here + +const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; + +class DOMClass implements dom.JSX.Element { + __domBrand!: void; + constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {} + render() { + return

{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}

; + } +} + +// Should work, everything is a DOM element +const _tree = + +// Should fail, no dom elements +const _brokenTree = + +// Should fail, nondom isn't allowed as children of dom +const _brokenTree2 = {tree}{tree} diff --git a/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx b/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx new file mode 100644 index 0000000000000..3f4340f518b4b --- /dev/null +++ b/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx @@ -0,0 +1,44 @@ +// @jsx: react +// @filename: renderer.d.ts +declare global { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __domBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function dom(): JSX.Element; +// @filename: renderer2.d.ts +export namespace predom { + namespace JSX { + interface IntrinsicElements { + [e: string]: {}; + } + interface Element { + __predomBrand: void; + children: Element[]; + props: {}; + } + interface ElementAttributesProperty { props: any; } + interface ElementChildrenAttribute { children: any; } + } +} +export function predom(): predom.JSX.Element; +// @filename: component.tsx +/** @jsx predom */ +import { predom } from "./renderer2" +export default + +// @filename: index.tsx +/** @jsx dom */ +import { dom } from "./renderer" +import prerendered from "./component"; +let elem = prerendered; +elem = ; // Expect assignability error here