diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e72a878371155..519e2533bf119 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4962,7 +4962,7 @@ namespace ts { const oldcontext = context; context = { ...oldcontext, - usedSymbolNames: mapMap(symbolTable, (_symbol, name) => [unescapeLeadingUnderscores(name), true]), + usedSymbolNames: createMap(), remappedSymbolNames: createMap(), tracker: { ...oldcontext.tracker, @@ -4986,6 +4986,10 @@ namespace ts { context.usedSymbolNames!.set(name, true); }); } + forEachEntry(symbolTable, (symbol, name) => { + const baseName = unescapeLeadingUnderscores(name); + void getInternalSymbolName(symbol, baseName); // Called to cache values into `usedSymbolNames` and `remappedSymbolNames` + }); let addingDeclare = !bundled; const exportEquals = symbolTable.get(InternalSymbolName.ExportEquals); if (exportEquals && symbolTable.size > 1 && exportEquals.flags & SymbolFlags.Alias) { @@ -5198,7 +5202,11 @@ namespace ts { isPrivate = true; } const modifierFlags = (!isPrivate ? ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ModifierFlags.Default : 0); - if (symbol.flags & SymbolFlags.Function) { + const isConstMergedWithNS = symbol.flags & SymbolFlags.Module && + symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) && + symbol.escapedName !== InternalSymbolName.ExportEquals; + const isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol); + if (symbol.flags & SymbolFlags.Function || isConstMergedWithNSPrintableAsSignatureMerge) { serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags); } if (symbol.flags & SymbolFlags.TypeAlias) { @@ -5209,7 +5217,8 @@ namespace ts { if (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) && symbol.escapedName !== InternalSymbolName.ExportEquals && !(symbol.flags & SymbolFlags.Prototype) - && !(symbol.flags & SymbolFlags.Class)) { + && !(symbol.flags & SymbolFlags.Class) + && !isConstMergedWithNSPrintableAsSignatureMerge) { serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags); } if (symbol.flags & SymbolFlags.Enum) { @@ -5226,7 +5235,7 @@ namespace ts { serializeAsClass(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags); } } - if (symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule)) { + if ((symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) { serializeModule(symbol, symbolName, modifierFlags); } if (symbol.flags & SymbolFlags.Interface) { @@ -5253,7 +5262,9 @@ namespace ts { } function includePrivateSymbol(symbol: Symbol) { + if (some(symbol.declarations, isParameterDeclaration)) return; Debug.assertDefined(deferredPrivates); + getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol deferredPrivates!.set("" + getSymbolId(symbol), symbol); } @@ -5327,8 +5338,16 @@ namespace ts { ), modifierFlags); } + function getNamespaceMembersForSerialization(symbol: Symbol) { + return !symbol.exports ? [] : filter(arrayFrom((symbol.exports).values()), p => !((p.flags & SymbolFlags.Prototype) || (p.escapedName === "prototype"))); + } + + function isTypeOnlyNamespace(symbol: Symbol) { + return every(getNamespaceMembersForSerialization(symbol), m => !(resolveSymbol(m).flags & SymbolFlags.Value)); + } + function serializeModule(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) { - const members = !symbol.exports ? [] : filter(arrayFrom((symbol.exports).values()), p => !((p.flags & SymbolFlags.Prototype) || (p.escapedName === "prototype"))); + const members = getNamespaceMembersForSerialization(symbol); // Split NS members up by declaration - members whose parent symbol is the ns symbol vs those whose is not (but were added in later via merging) const locationMap = arrayToMultiMap(members, m => m.parent && m.parent === symbol ? "real" : "merged"); const realMembers = locationMap.get("real") || emptyArray; @@ -5338,18 +5357,21 @@ namespace ts { // so we don't even have placeholders to fill in. if (length(realMembers)) { const localName = getInternalSymbolName(symbol, symbolName); - serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & SymbolFlags.Function)); + serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & (SymbolFlags.Function | SymbolFlags.Assignment))); } if (length(mergedMembers)) { const localName = getInternalSymbolName(symbol, symbolName); - forEach(mergedMembers, includePrivateSymbol); const nsBody = createModuleBlock([createExportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports(map(filter(mergedMembers, n => n.escapedName !== InternalSymbolName.ExportEquals), s => { const name = unescapeLeadingUnderscores(s.escapedName); const localName = getInternalSymbolName(s, name); - return createExportSpecifier(name === localName ? undefined : localName, name); + const aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s); + const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); + includePrivateSymbol(target || s); + const targetName = target ? getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)) : localName; + return createExportSpecifier(name === targetName ? undefined : targetName, name); })) )]); addResult(createModuleDeclaration( @@ -5624,6 +5646,7 @@ namespace ts { serializeMaybeAliasAssignment(symbol); break; case SyntaxKind.BinaryExpression: + case SyntaxKind.PropertyAccessExpression: // Could be best encoded as though an export specifier or as though an export assignment // If name is default or export=, do an export assignment // Otherwise do an export specifier @@ -5634,10 +5657,6 @@ namespace ts { serializeExportSpecifier(localName, targetName); } break; - case SyntaxKind.PropertyAccessExpression: - // A PAE alias is _always_ going to exist as an append to a top-level export, where our top level - // handling should always be sufficient to encode the export action itself - break; default: return Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!"); } @@ -5666,7 +5685,8 @@ namespace ts { const aliasDecl = symbol.declarations && getDeclarationOfAliasSymbol(symbol); // serialize what the alias points to, preserve the declaration's initializer const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); - if (target) { + // If the target resolves and resolves to a thing defined in this file, emit as an alias, otherwise emit as a const + if (target && length(target.declarations) && some(target.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(enclosingDeclaration))) { // In case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it // eg, `namespace A { export class B {} }; exports = A.B;` // Technically, this is all that's required in the case where the assignment is an entity name expression @@ -5752,6 +5772,7 @@ namespace ts { return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) && !getIndexInfoOfType(typeToSerialize, IndexKind.String) && !getIndexInfoOfType(typeToSerialize, IndexKind.Number) && + !!(length(getPropertiesOfType(typeToSerialize)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) && !length(getSignaturesOfType(typeToSerialize, SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK !getDeclarationWithTypeAnnotation(hostSymbol) && !(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && @@ -6106,11 +6127,8 @@ namespace ts { return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; } } - if (input === InternalSymbolName.Default) { - input = "_default"; - } - else if (input === InternalSymbolName.ExportEquals) { - input = "_exports"; + if (symbol) { + input = getNameCandidateWorker(symbol, input); } let i = 0; const original = input; @@ -6125,17 +6143,29 @@ namespace ts { return input; } - function getInternalSymbolName(symbol: Symbol, localName: string) { - if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { - return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; - } + function getNameCandidateWorker(symbol: Symbol, localName: string) { if (localName === InternalSymbolName.Default || localName === InternalSymbolName.Class || localName === InternalSymbolName.Function) { const flags = context.flags; context.flags |= NodeBuilderFlags.InInitialEntityName; const nameCandidate = getNameOfSymbolAsWritten(symbol, context); context.flags = flags; - localName = isIdentifierText(nameCandidate, languageVersion) && !isStringANonContextualKeyword(nameCandidate) ? nameCandidate : getUnusedName(`_default`, symbol); + localName = nameCandidate.length > 0 && isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? stripQuotes(nameCandidate) : nameCandidate; + } + if (localName === InternalSymbolName.Default) { + localName = "_default"; + } + else if (localName === InternalSymbolName.ExportEquals) { + localName = "_exports"; + } + localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_"); + return localName; + } + + function getInternalSymbolName(symbol: Symbol, localName: string) { + if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { + return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; } + localName = getNameCandidateWorker(symbol, localName); // The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up context.remappedSymbolNames!.set("" + getSymbolId(symbol), localName); return localName; diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.js b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.js index df093050b7c49..59bd72937862f 100644 --- a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.js +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.js @@ -1,5 +1,4 @@ //// [index.js] -// TODO: Fixup class A { member = new Q(); } @@ -15,7 +14,6 @@ module.exports.Another = Q; //// [index.js] -// TODO: Fixup var A = /** @class */ (function () { function A() { this.member = new Q(); @@ -43,44 +41,11 @@ declare class Q { x: A; } declare namespace Q { - export { Another }; + export { Q_1 as Another }; } declare class A { member: Q; } -declare var Another: typeof Q; -declare class Q { +declare class Q_1 { x: number; } - - -//// [DtsFileErrors] - - -out/index.d.ts(2,15): error TS2300: Duplicate identifier 'Q'. -out/index.d.ts(5,19): error TS2300: Duplicate identifier 'Q'. -out/index.d.ts(12,15): error TS2300: Duplicate identifier 'Q'. - - -==== ./out/index.d.ts (3 errors) ==== - export = Q; - declare class Q { - ~ -!!! error TS2300: Duplicate identifier 'Q'. - x: A; - } - declare namespace Q { - ~ -!!! error TS2300: Duplicate identifier 'Q'. - export { Another }; - } - declare class A { - member: Q; - } - declare var Another: typeof Q; - declare class Q { - ~ -!!! error TS2300: Duplicate identifier 'Q'. - x: number; - } - \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.symbols index 37f1cf9124daf..40a6fb56147ff 100644 --- a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.symbols +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.symbols @@ -1,37 +1,36 @@ === tests/cases/conformance/jsdoc/declarations/index.js === -// TODO: Fixup class A { >A : Symbol(A, Decl(index.js, 0, 0)) member = new Q(); ->member : Symbol(A.member, Decl(index.js, 1, 9)) ->Q : Symbol(Q, Decl(index.js, 3, 1)) +>member : Symbol(A.member, Decl(index.js, 0, 9)) +>Q : Symbol(Q, Decl(index.js, 2, 1)) } class Q { ->Q : Symbol(Q, Decl(index.js, 3, 1)) +>Q : Symbol(Q, Decl(index.js, 2, 1)) x = 42; ->x : Symbol(Q.x, Decl(index.js, 4, 9)) +>x : Symbol(Q.x, Decl(index.js, 3, 9)) } module.exports = class Q { >module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) ->module : Symbol(export=, Decl(index.js, 6, 1)) ->exports : Symbol(export=, Decl(index.js, 6, 1)) ->Q : Symbol(Q, Decl(index.js, 7, 16)) +>module : Symbol(export=, Decl(index.js, 5, 1)) +>exports : Symbol(export=, Decl(index.js, 5, 1)) +>Q : Symbol(Q, Decl(index.js, 6, 16)) constructor() { this.x = new A(); ->this.x : Symbol(Q.x, Decl(index.js, 8, 19)) ->this : Symbol(Q, Decl(index.js, 7, 16)) ->x : Symbol(Q.x, Decl(index.js, 8, 19)) +>this.x : Symbol(Q.x, Decl(index.js, 7, 19)) +>this : Symbol(Q, Decl(index.js, 6, 16)) +>x : Symbol(Q.x, Decl(index.js, 7, 19)) >A : Symbol(A, Decl(index.js, 0, 0)) } } module.exports.Another = Q; >module.exports.Another : Symbol(Another) ->module.exports : Symbol(Another, Decl(index.js, 11, 1)) ->module : Symbol(module, Decl(index.js, 6, 1)) +>module.exports : Symbol(Another, Decl(index.js, 10, 1)) +>module : Symbol(module, Decl(index.js, 5, 1)) >exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) ->Another : Symbol(Another, Decl(index.js, 11, 1)) ->Q : Symbol(Q, Decl(index.js, 3, 1)) +>Another : Symbol(Another, Decl(index.js, 10, 1)) +>Q : Symbol(Q, Decl(index.js, 2, 1)) diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.types b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.types index bd3594e288403..2a8d6a1b927dc 100644 --- a/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.types +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassExpressionShadowing.types @@ -1,5 +1,4 @@ === tests/cases/conformance/jsdoc/declarations/index.js === -// TODO: Fixup class A { >A : A diff --git a/tests/baselines/reference/jsDeclarationsFunctionsCjs.js b/tests/baselines/reference/jsDeclarationsFunctionsCjs.js index 6e80a0b4b17c6..cc29b4daf6c17 100644 --- a/tests/baselines/reference/jsDeclarationsFunctionsCjs.js +++ b/tests/baselines/reference/jsDeclarationsFunctionsCjs.js @@ -121,8 +121,7 @@ export namespace b { } export function c(): void; export namespace c { - class Cls { - } + export { Cls }; } export function d(a: number, b: number): string; export function e(a: T, b: U): T & U; @@ -159,3 +158,6 @@ export function i(): void; export function ii(): void; export function jj(): void; export function j(): void; +declare class Cls { +} +export {}; diff --git a/tests/baselines/reference/jsDeclarationsReactComponents.js b/tests/baselines/reference/jsDeclarationsReactComponents.js new file mode 100644 index 0000000000000..025a96adddac4 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsReactComponents.js @@ -0,0 +1,246 @@ +//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents.ts] //// + +//// [jsDeclarationsReactComponents1.jsx] +/// +import React from "react"; +import PropTypes from "prop-types" + +const TabbedShowLayout = ({ +}) => { + return ( +
+ ); +}; + +TabbedShowLayout.propTypes = { + version: PropTypes.number, + +}; + +TabbedShowLayout.defaultProps = { + tabs: undefined +}; + +export default TabbedShowLayout; + +//// [jsDeclarationsReactComponents2.jsx] +import React from "react"; +/** + * @type {React.SFC} + */ +const TabbedShowLayout = () => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; + +//// [jsDeclarationsReactComponents3.jsx] +import React from "react"; +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +const TabbedShowLayout = () => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; + +//// [jsDeclarationsReactComponents4.jsx] +import React from "react"; +const TabbedShowLayout = (/** @type {{className: string}}*/prop) => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; +//// [jsDeclarationsReactComponents5.jsx] +import React from 'react'; +import PropTypes from 'prop-types'; + +function Tree({ allowDropOnRoot }) { + return
+} + +Tree.propTypes = { + classes: PropTypes.object, +}; + +Tree.defaultProps = { + classes: {}, + parentSource: 'parent_id', +}; + +export default Tree; + +//// [jsDeclarationsReactComponents1.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/// +var react_1 = __importDefault(require("react")); +var prop_types_1 = __importDefault(require("prop-types")); +var TabbedShowLayout = function (_a) { + return (react_1.default.createElement("div", null)); +}; +TabbedShowLayout.propTypes = { + version: prop_types_1.default.number, +}; +TabbedShowLayout.defaultProps = { + tabs: undefined +}; +exports.default = TabbedShowLayout; +//// [jsDeclarationsReactComponents2.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var react_1 = __importDefault(require("react")); +/** + * @type {React.SFC} + */ +var TabbedShowLayout = function () { + return (react_1.default.createElement("div", { className: "", key: "" }, "ok")); +}; +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; +exports.default = TabbedShowLayout; +//// [jsDeclarationsReactComponents3.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var react_1 = __importDefault(require("react")); +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +var TabbedShowLayout = function () { + return (react_1.default.createElement("div", { className: "", key: "" }, "ok")); +}; +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; +exports.default = TabbedShowLayout; +//// [jsDeclarationsReactComponents4.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var react_1 = __importDefault(require("react")); +var TabbedShowLayout = function (/** @type {{className: string}}*/ prop) { + return (react_1.default.createElement("div", { className: prop.className, key: "" }, "ok")); +}; +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; +exports.default = TabbedShowLayout; +//// [jsDeclarationsReactComponents5.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var react_1 = __importDefault(require("react")); +var prop_types_1 = __importDefault(require("prop-types")); +function Tree(_a) { + var allowDropOnRoot = _a.allowDropOnRoot; + return react_1.default.createElement("div", null); +} +Tree.propTypes = { + classes: prop_types_1.default.object, +}; +Tree.defaultProps = { + classes: {}, + parentSource: 'parent_id', +}; +exports.default = Tree; + + +//// [jsDeclarationsReactComponents1.d.ts] +/// +export default TabbedShowLayout; +declare function TabbedShowLayout({}: {}): JSX.Element; +declare namespace TabbedShowLayout { + export namespace propTypes { + export const version: PropTypes.Requireable; + } + export namespace defaultProps { + export const tabs: undefined; + } +} +import PropTypes from "prop-types"; +//// [jsDeclarationsReactComponents2.d.ts] +/// +export default TabbedShowLayout; +/** + * @type {React.SFC} + */ +declare const TabbedShowLayout: React.SFC; +import React from "react"; +//// [jsDeclarationsReactComponents3.d.ts] +export default TabbedShowLayout; +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +declare const TabbedShowLayout: { + defaultProps: { + tabs: string; + }; +} & ((props?: { + elem: string; +}) => JSX.Element); +//// [jsDeclarationsReactComponents4.d.ts] +export default TabbedShowLayout; +declare function TabbedShowLayout(prop: { + className: string; +}): JSX.Element; +declare namespace TabbedShowLayout { + export namespace defaultProps { + export const tabs: string; + } +} +//// [jsDeclarationsReactComponents5.d.ts] +/// +export default Tree; +declare function Tree({ allowDropOnRoot }: { + allowDropOnRoot: any; +}): JSX.Element; +declare namespace Tree { + export namespace propTypes { + export const classes: PropTypes.Requireable; + } + export namespace defaultProps { + const classes_1: {}; + export { classes_1 as classes }; + export const parentSource: string; + } +} +import PropTypes from "prop-types"; diff --git a/tests/baselines/reference/jsDeclarationsReactComponents.symbols b/tests/baselines/reference/jsDeclarationsReactComponents.symbols new file mode 100644 index 0000000000000..43739a502a000 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsReactComponents.symbols @@ -0,0 +1,199 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents1.jsx === +/// +import React from "react"; +>React : Symbol(React, Decl(jsDeclarationsReactComponents1.jsx, 1, 6)) + +import PropTypes from "prop-types" +>PropTypes : Symbol(PropTypes, Decl(jsDeclarationsReactComponents1.jsx, 2, 6)) + +const TabbedShowLayout = ({ +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents1.jsx, 4, 5), Decl(jsDeclarationsReactComponents1.jsx, 9, 2), Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) + +}) => { + return ( +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + + ); +}; + +TabbedShowLayout.propTypes = { +>TabbedShowLayout.propTypes : Symbol(TabbedShowLayout.propTypes, Decl(jsDeclarationsReactComponents1.jsx, 9, 2)) +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents1.jsx, 4, 5), Decl(jsDeclarationsReactComponents1.jsx, 9, 2), Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) +>propTypes : Symbol(TabbedShowLayout.propTypes, Decl(jsDeclarationsReactComponents1.jsx, 9, 2)) + + version: PropTypes.number, +>version : Symbol(version, Decl(jsDeclarationsReactComponents1.jsx, 11, 30)) +>PropTypes.number : Symbol(PropTypes.number, Decl(react16.d.ts, 64, 16)) +>PropTypes : Symbol(PropTypes, Decl(jsDeclarationsReactComponents1.jsx, 2, 6)) +>number : Symbol(PropTypes.number, Decl(react16.d.ts, 64, 16)) + +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps : Symbol(TabbedShowLayout.defaultProps, Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents1.jsx, 4, 5), Decl(jsDeclarationsReactComponents1.jsx, 9, 2), Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) +>defaultProps : Symbol(TabbedShowLayout.defaultProps, Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) + + tabs: undefined +>tabs : Symbol(tabs, Decl(jsDeclarationsReactComponents1.jsx, 16, 33)) +>undefined : Symbol(undefined) + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents1.jsx, 4, 5), Decl(jsDeclarationsReactComponents1.jsx, 9, 2), Decl(jsDeclarationsReactComponents1.jsx, 14, 2)) + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents2.jsx === +import React from "react"; +>React : Symbol(React, Decl(jsDeclarationsReactComponents2.jsx, 0, 6)) + +/** + * @type {React.SFC} + */ +const TabbedShowLayout = () => { +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents2.jsx, 4, 5), Decl(jsDeclarationsReactComponents2.jsx, 10, 2)) + + return ( +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>className : Symbol(className, Decl(jsDeclarationsReactComponents2.jsx, 6, 12)) +>key : Symbol(key, Decl(jsDeclarationsReactComponents2.jsx, 6, 25)) + + ok +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps : Symbol(React.StatelessComponent.defaultProps, Decl(react16.d.ts, 410, 46)) +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents2.jsx, 4, 5), Decl(jsDeclarationsReactComponents2.jsx, 10, 2)) +>defaultProps : Symbol(React.StatelessComponent.defaultProps, Decl(react16.d.ts, 410, 46)) + + tabs: "default value" +>tabs : Symbol(tabs, Decl(jsDeclarationsReactComponents2.jsx, 12, 33)) + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents2.jsx, 4, 5), Decl(jsDeclarationsReactComponents2.jsx, 10, 2)) + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents3.jsx === +import React from "react"; +>React : Symbol(React, Decl(jsDeclarationsReactComponents3.jsx, 0, 6)) + +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +const TabbedShowLayout = () => { +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents3.jsx, 4, 5), Decl(jsDeclarationsReactComponents3.jsx, 10, 2)) + + return ( +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>className : Symbol(className, Decl(jsDeclarationsReactComponents3.jsx, 6, 12)) +>key : Symbol(key, Decl(jsDeclarationsReactComponents3.jsx, 6, 25)) + + ok +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps : Symbol(defaultProps, Decl(jsDeclarationsReactComponents3.jsx, 2, 11)) +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents3.jsx, 4, 5), Decl(jsDeclarationsReactComponents3.jsx, 10, 2)) +>defaultProps : Symbol(defaultProps, Decl(jsDeclarationsReactComponents3.jsx, 2, 11)) + + tabs: "default value" +>tabs : Symbol(tabs, Decl(jsDeclarationsReactComponents3.jsx, 12, 33)) + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents3.jsx, 4, 5), Decl(jsDeclarationsReactComponents3.jsx, 10, 2)) + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents4.jsx === +import React from "react"; +>React : Symbol(React, Decl(jsDeclarationsReactComponents4.jsx, 0, 6)) + +const TabbedShowLayout = (/** @type {{className: string}}*/prop) => { +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents4.jsx, 1, 5), Decl(jsDeclarationsReactComponents4.jsx, 7, 2)) +>prop : Symbol(prop, Decl(jsDeclarationsReactComponents4.jsx, 1, 26)) + + return ( +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>className : Symbol(className, Decl(jsDeclarationsReactComponents4.jsx, 3, 12)) +>prop.className : Symbol(className, Decl(jsDeclarationsReactComponents4.jsx, 1, 38)) +>prop : Symbol(prop, Decl(jsDeclarationsReactComponents4.jsx, 1, 26)) +>className : Symbol(className, Decl(jsDeclarationsReactComponents4.jsx, 1, 38)) +>key : Symbol(key, Decl(jsDeclarationsReactComponents4.jsx, 3, 39)) + + ok +
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps : Symbol(TabbedShowLayout.defaultProps, Decl(jsDeclarationsReactComponents4.jsx, 7, 2)) +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents4.jsx, 1, 5), Decl(jsDeclarationsReactComponents4.jsx, 7, 2)) +>defaultProps : Symbol(TabbedShowLayout.defaultProps, Decl(jsDeclarationsReactComponents4.jsx, 7, 2)) + + tabs: "default value" +>tabs : Symbol(tabs, Decl(jsDeclarationsReactComponents4.jsx, 9, 33)) + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : Symbol(TabbedShowLayout, Decl(jsDeclarationsReactComponents4.jsx, 1, 5), Decl(jsDeclarationsReactComponents4.jsx, 7, 2)) + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents5.jsx === +import React from 'react'; +>React : Symbol(React, Decl(jsDeclarationsReactComponents5.jsx, 0, 6)) + +import PropTypes from 'prop-types'; +>PropTypes : Symbol(PropTypes, Decl(jsDeclarationsReactComponents5.jsx, 1, 6)) + +function Tree({ allowDropOnRoot }) { +>Tree : Symbol(Tree, Decl(jsDeclarationsReactComponents5.jsx, 1, 35), Decl(jsDeclarationsReactComponents5.jsx, 5, 1), Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) +>allowDropOnRoot : Symbol(allowDropOnRoot, Decl(jsDeclarationsReactComponents5.jsx, 3, 15)) + + return
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +} + +Tree.propTypes = { +>Tree.propTypes : Symbol(Tree.propTypes, Decl(jsDeclarationsReactComponents5.jsx, 5, 1)) +>Tree : Symbol(Tree, Decl(jsDeclarationsReactComponents5.jsx, 1, 35), Decl(jsDeclarationsReactComponents5.jsx, 5, 1), Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) +>propTypes : Symbol(Tree.propTypes, Decl(jsDeclarationsReactComponents5.jsx, 5, 1)) + + classes: PropTypes.object, +>classes : Symbol(classes, Decl(jsDeclarationsReactComponents5.jsx, 7, 18)) +>PropTypes.object : Symbol(PropTypes.object, Decl(react16.d.ts, 65, 16)) +>PropTypes : Symbol(PropTypes, Decl(jsDeclarationsReactComponents5.jsx, 1, 6)) +>object : Symbol(PropTypes.object, Decl(react16.d.ts, 65, 16)) + +}; + +Tree.defaultProps = { +>Tree.defaultProps : Symbol(Tree.defaultProps, Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) +>Tree : Symbol(Tree, Decl(jsDeclarationsReactComponents5.jsx, 1, 35), Decl(jsDeclarationsReactComponents5.jsx, 5, 1), Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) +>defaultProps : Symbol(Tree.defaultProps, Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) + + classes: {}, +>classes : Symbol(classes, Decl(jsDeclarationsReactComponents5.jsx, 11, 21)) + + parentSource: 'parent_id', +>parentSource : Symbol(parentSource, Decl(jsDeclarationsReactComponents5.jsx, 12, 16)) + +}; + +export default Tree; +>Tree : Symbol(Tree, Decl(jsDeclarationsReactComponents5.jsx, 1, 35), Decl(jsDeclarationsReactComponents5.jsx, 5, 1), Decl(jsDeclarationsReactComponents5.jsx, 9, 2)) + diff --git a/tests/baselines/reference/jsDeclarationsReactComponents.types b/tests/baselines/reference/jsDeclarationsReactComponents.types new file mode 100644 index 0000000000000..260eedaff26ad --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsReactComponents.types @@ -0,0 +1,235 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents1.jsx === +/// +import React from "react"; +>React : typeof React + +import PropTypes from "prop-types" +>PropTypes : typeof PropTypes + +const TabbedShowLayout = ({ +>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable; }; defaultProps: { tabs: undefined; }; } +>({}) => { return (
);} : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable; }; defaultProps: { tabs: undefined; }; } + +}) => { + return ( +>(
) : JSX.Element + +
+>
: JSX.Element +>div : any + + ); +}; + +TabbedShowLayout.propTypes = { +>TabbedShowLayout.propTypes = { version: PropTypes.number,} : { version: PropTypes.Requireable; } +>TabbedShowLayout.propTypes : { version: PropTypes.Requireable; } +>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable; }; defaultProps: { tabs: undefined; }; } +>propTypes : { version: PropTypes.Requireable; } +>{ version: PropTypes.number,} : { version: PropTypes.Requireable; } + + version: PropTypes.number, +>version : PropTypes.Requireable +>PropTypes.number : PropTypes.Requireable +>PropTypes : typeof PropTypes +>number : PropTypes.Requireable + +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps = { tabs: undefined} : { tabs: undefined; } +>TabbedShowLayout.defaultProps : { tabs: undefined; } +>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable; }; defaultProps: { tabs: undefined; }; } +>defaultProps : { tabs: undefined; } +>{ tabs: undefined} : { tabs: undefined; } + + tabs: undefined +>tabs : undefined +>undefined : undefined + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable; }; defaultProps: { tabs: undefined; }; } + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents2.jsx === +import React from "react"; +>React : typeof React + +/** + * @type {React.SFC} + */ +const TabbedShowLayout = () => { +>TabbedShowLayout : React.SFC<{}> +>() => { return (
ok
);} : { (): JSX.Element; defaultProps: Partial<{}> | undefined; } + + return ( +>(
ok
) : JSX.Element + +
+>
ok
: JSX.Element +>div : any +>className : string +>key : string + + ok +
+>div : any + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps = { tabs: "default value"} : { tabs: string; } +>TabbedShowLayout.defaultProps : Partial<{}> | undefined +>TabbedShowLayout : React.SFC<{}> +>defaultProps : Partial<{}> | undefined +>{ tabs: "default value"} : { tabs: string; } + + tabs: "default value" +>tabs : string +>"default value" : "default value" + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : React.SFC<{}> + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents3.jsx === +import React from "react"; +>React : typeof React + +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +const TabbedShowLayout = () => { +>TabbedShowLayout : { defaultProps: { tabs: string; }; } & ((props?: { elem: string; } | undefined) => JSX.Element) +>() => { return (
ok
);} : { (): JSX.Element; defaultProps: { tabs: string; }; } + + return ( +>(
ok
) : JSX.Element + +
+>
ok
: JSX.Element +>div : any +>className : string +>key : string + + ok +
+>div : any + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps = { tabs: "default value"} : { tabs: string; } +>TabbedShowLayout.defaultProps : { tabs: string; } +>TabbedShowLayout : { defaultProps: { tabs: string; }; } & ((props?: { elem: string; } | undefined) => JSX.Element) +>defaultProps : { tabs: string; } +>{ tabs: "default value"} : { tabs: string; } + + tabs: "default value" +>tabs : string +>"default value" : "default value" + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : { defaultProps: { tabs: string; }; } & ((props?: { elem: string; } | undefined) => JSX.Element) + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents4.jsx === +import React from "react"; +>React : typeof React + +const TabbedShowLayout = (/** @type {{className: string}}*/prop) => { +>TabbedShowLayout : { (prop: { className: string; }): JSX.Element; defaultProps: { tabs: string; }; } +>(/** @type {{className: string}}*/prop) => { return (
ok
);} : { (prop: { className: string; }): JSX.Element; defaultProps: { tabs: string; }; } +>prop : { className: string; } + + return ( +>(
ok
) : JSX.Element + +
+>
ok
: JSX.Element +>div : any +>className : string +>prop.className : string +>prop : { className: string; } +>className : string +>key : string + + ok +
+>div : any + + ); +}; + +TabbedShowLayout.defaultProps = { +>TabbedShowLayout.defaultProps = { tabs: "default value"} : { tabs: string; } +>TabbedShowLayout.defaultProps : { tabs: string; } +>TabbedShowLayout : { (prop: { className: string; }): JSX.Element; defaultProps: { tabs: string; }; } +>defaultProps : { tabs: string; } +>{ tabs: "default value"} : { tabs: string; } + + tabs: "default value" +>tabs : string +>"default value" : "default value" + +}; + +export default TabbedShowLayout; +>TabbedShowLayout : { (prop: { className: string; }): JSX.Element; defaultProps: { tabs: string; }; } + +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents5.jsx === +import React from 'react'; +>React : typeof React + +import PropTypes from 'prop-types'; +>PropTypes : typeof PropTypes + +function Tree({ allowDropOnRoot }) { +>Tree : typeof Tree +>allowDropOnRoot : any + + return
+>
: JSX.Element +>div : any +} + +Tree.propTypes = { +>Tree.propTypes = { classes: PropTypes.object,} : { classes: PropTypes.Requireable; } +>Tree.propTypes : { classes: PropTypes.Requireable; } +>Tree : typeof Tree +>propTypes : { classes: PropTypes.Requireable; } +>{ classes: PropTypes.object,} : { classes: PropTypes.Requireable; } + + classes: PropTypes.object, +>classes : PropTypes.Requireable +>PropTypes.object : PropTypes.Requireable +>PropTypes : typeof PropTypes +>object : PropTypes.Requireable + +}; + +Tree.defaultProps = { +>Tree.defaultProps = { classes: {}, parentSource: 'parent_id',} : { classes: {}; parentSource: string; } +>Tree.defaultProps : { classes: {}; parentSource: string; } +>Tree : typeof Tree +>defaultProps : { classes: {}; parentSource: string; } +>{ classes: {}, parentSource: 'parent_id',} : { classes: {}; parentSource: string; } + + classes: {}, +>classes : {} +>{} : {} + + parentSource: 'parent_id', +>parentSource : string +>'parent_id' : "parent_id" + +}; + +export default Tree; +>Tree : typeof Tree + diff --git a/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js index f35fad8297bbd..2aefd95141a2a 100644 --- a/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js +++ b/tests/baselines/reference/jsxDeclarationsWithEsModuleInteropNoCrash.js @@ -33,8 +33,7 @@ declare namespace Foo { export { defaultProps }; } declare namespace propTypes { - import bar = PropTypes.bool; - export { bar }; + export const bar: PropTypes.Requireable; } declare namespace defaultProps { const bar_1: boolean; diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassExpressionShadowing.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassExpressionShadowing.ts index 847632ca970cd..2029a93d0dec8 100644 --- a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassExpressionShadowing.ts +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassExpressionShadowing.ts @@ -4,7 +4,6 @@ // @outDir: ./out // @declaration: true // @filename: index.js -// TODO: Fixup class A { member = new Q(); } diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents.ts new file mode 100644 index 0000000000000..ce09708e9c4d4 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents.ts @@ -0,0 +1,103 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @jsx: react +// @esModuleInterop: true +// @outDir: ./out +// @strict: true +// @noImplicitAny: false +// @declaration: true +// @filename: jsDeclarationsReactComponents1.jsx +/// +import React from "react"; +import PropTypes from "prop-types" + +const TabbedShowLayout = ({ +}) => { + return ( +
+ ); +}; + +TabbedShowLayout.propTypes = { + version: PropTypes.number, + +}; + +TabbedShowLayout.defaultProps = { + tabs: undefined +}; + +export default TabbedShowLayout; + +// @filename: jsDeclarationsReactComponents2.jsx +import React from "react"; +/** + * @type {React.SFC} + */ +const TabbedShowLayout = () => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; + +// @filename: jsDeclarationsReactComponents3.jsx +import React from "react"; +/** + * @type {{defaultProps: {tabs: string}} & ((props?: {elem: string}) => JSX.Element)} + */ +const TabbedShowLayout = () => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; + +// @filename: jsDeclarationsReactComponents4.jsx +import React from "react"; +const TabbedShowLayout = (/** @type {{className: string}}*/prop) => { + return ( +
+ ok +
+ ); +}; + +TabbedShowLayout.defaultProps = { + tabs: "default value" +}; + +export default TabbedShowLayout; +// @filename: jsDeclarationsReactComponents5.jsx +import React from 'react'; +import PropTypes from 'prop-types'; + +function Tree({ allowDropOnRoot }) { + return
+} + +Tree.propTypes = { + classes: PropTypes.object, +}; + +Tree.defaultProps = { + classes: {}, + parentSource: 'parent_id', +}; + +export default Tree; \ No newline at end of file