Fix alias naming and structure bugs in js declarations (#34786)

* Fix alias naming and structure bugs in js declarations

* Add another test case and change condition for ns merge to require signature or export content

* Fix typo in comment
This commit is contained in:
Wesley Wigham 2019-10-30 12:40:06 -07:00 committed by GitHub
parent 87cc8c4af8
commit d28672d97f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 857 additions and 81 deletions

View File

@ -4968,7 +4968,7 @@ namespace ts {
const oldcontext = context;
context = {
...oldcontext,
usedSymbolNames: mapMap(symbolTable, (_symbol, name) => [unescapeLeadingUnderscores(name), true]),
usedSymbolNames: createMap(),
remappedSymbolNames: createMap(),
tracker: {
...oldcontext.tracker,
@ -4992,6 +4992,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) {
@ -5204,7 +5208,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) {
@ -5215,7 +5223,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) {
@ -5232,7 +5241,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) {
@ -5259,7 +5268,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);
}
@ -5333,8 +5344,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;
@ -5344,18 +5363,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(
@ -5630,6 +5652,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
@ -5640,10 +5663,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!");
}
@ -5672,7 +5691,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
@ -5758,6 +5778,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)) &&
@ -6112,11 +6133,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;
@ -6131,17 +6149,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;

View File

@ -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;
}

View File

@ -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))

View File

@ -1,5 +1,4 @@
=== tests/cases/conformance/jsdoc/declarations/index.js ===
// TODO: Fixup
class A {
>A : A

View File

@ -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<T, U>(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 {};

View File

@ -0,0 +1,246 @@
//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents.ts] ////
//// [jsDeclarationsReactComponents1.jsx]
/// <reference path="/.lib/react16.d.ts" />
import React from "react";
import PropTypes from "prop-types"
const TabbedShowLayout = ({
}) => {
return (
<div />
);
};
TabbedShowLayout.propTypes = {
version: PropTypes.number,
};
TabbedShowLayout.defaultProps = {
tabs: undefined
};
export default TabbedShowLayout;
//// [jsDeclarationsReactComponents2.jsx]
import React from "react";
/**
* @type {React.SFC}
*/
const TabbedShowLayout = () => {
return (
<div className="" key="">
ok
</div>
);
};
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 (
<div className="" key="">
ok
</div>
);
};
TabbedShowLayout.defaultProps = {
tabs: "default value"
};
export default TabbedShowLayout;
//// [jsDeclarationsReactComponents4.jsx]
import React from "react";
const TabbedShowLayout = (/** @type {{className: string}}*/prop) => {
return (
<div className={prop.className} key="">
ok
</div>
);
};
TabbedShowLayout.defaultProps = {
tabs: "default value"
};
export default TabbedShowLayout;
//// [jsDeclarationsReactComponents5.jsx]
import React from 'react';
import PropTypes from 'prop-types';
function Tree({ allowDropOnRoot }) {
return <div />
}
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 });
/// <reference path="react16.d.ts" />
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]
/// <reference path="../..react16.d.ts" />
export default TabbedShowLayout;
declare function TabbedShowLayout({}: {}): JSX.Element;
declare namespace TabbedShowLayout {
export namespace propTypes {
export const version: PropTypes.Requireable<number>;
}
export namespace defaultProps {
export const tabs: undefined;
}
}
import PropTypes from "prop-types";
//// [jsDeclarationsReactComponents2.d.ts]
/// <reference path="../..react16.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]
/// <reference path="../..react16.d.ts" />
export default Tree;
declare function Tree({ allowDropOnRoot }: {
allowDropOnRoot: any;
}): JSX.Element;
declare namespace Tree {
export namespace propTypes {
export const classes: PropTypes.Requireable<object>;
}
export namespace defaultProps {
const classes_1: {};
export { classes_1 as classes };
export const parentSource: string;
}
}
import PropTypes from "prop-types";

View File

@ -0,0 +1,199 @@
=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents1.jsx ===
/// <reference path="react16.d.ts" />
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 />
>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 className="" key="">
>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>
>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 className="" key="">
>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>
>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 className={prop.className} key="">
>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>
>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 />
>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))

View File

@ -0,0 +1,235 @@
=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsReactComponents1.jsx ===
/// <reference path="react16.d.ts" />
import React from "react";
>React : typeof React
import PropTypes from "prop-types"
>PropTypes : typeof PropTypes
const TabbedShowLayout = ({
>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable<number>; }; defaultProps: { tabs: undefined; }; }
>({}) => { return ( <div /> );} : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable<number>; }; defaultProps: { tabs: undefined; }; }
}) => {
return (
>( <div /> ) : JSX.Element
<div />
><div /> : JSX.Element
>div : any
);
};
TabbedShowLayout.propTypes = {
>TabbedShowLayout.propTypes = { version: PropTypes.number,} : { version: PropTypes.Requireable<number>; }
>TabbedShowLayout.propTypes : { version: PropTypes.Requireable<number>; }
>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable<number>; }; defaultProps: { tabs: undefined; }; }
>propTypes : { version: PropTypes.Requireable<number>; }
>{ version: PropTypes.number,} : { version: PropTypes.Requireable<number>; }
version: PropTypes.number,
>version : PropTypes.Requireable<number>
>PropTypes.number : PropTypes.Requireable<number>
>PropTypes : typeof PropTypes
>number : PropTypes.Requireable<number>
};
TabbedShowLayout.defaultProps = {
>TabbedShowLayout.defaultProps = { tabs: undefined} : { tabs: undefined; }
>TabbedShowLayout.defaultProps : { tabs: undefined; }
>TabbedShowLayout : { ({}: {}): JSX.Element; propTypes: { version: PropTypes.Requireable<number>; }; 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<number>; }; 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 ( <div className="" key=""> ok </div> );} : { (): JSX.Element; defaultProps: Partial<{}> | undefined; }
return (
>( <div className="" key=""> ok </div> ) : JSX.Element
<div className="" key="">
><div className="" key=""> ok </div> : JSX.Element
>div : any
>className : string
>key : string
ok
</div>
>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 ( <div className="" key=""> ok </div> );} : { (): JSX.Element; defaultProps: { tabs: string; }; }
return (
>( <div className="" key=""> ok </div> ) : JSX.Element
<div className="" key="">
><div className="" key=""> ok </div> : JSX.Element
>div : any
>className : string
>key : string
ok
</div>
>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 ( <div className={prop.className} key=""> ok </div> );} : { (prop: { className: string; }): JSX.Element; defaultProps: { tabs: string; }; }
>prop : { className: string; }
return (
>( <div className={prop.className} key=""> ok </div> ) : JSX.Element
<div className={prop.className} key="">
><div className={prop.className} key=""> ok </div> : JSX.Element
>div : any
>className : string
>prop.className : string
>prop : { className: string; }
>className : string
>key : string
ok
</div>
>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 <div />
><div /> : JSX.Element
>div : any
}
Tree.propTypes = {
>Tree.propTypes = { classes: PropTypes.object,} : { classes: PropTypes.Requireable<object>; }
>Tree.propTypes : { classes: PropTypes.Requireable<object>; }
>Tree : typeof Tree
>propTypes : { classes: PropTypes.Requireable<object>; }
>{ classes: PropTypes.object,} : { classes: PropTypes.Requireable<object>; }
classes: PropTypes.object,
>classes : PropTypes.Requireable<object>
>PropTypes.object : PropTypes.Requireable<object>
>PropTypes : typeof PropTypes
>object : PropTypes.Requireable<object>
};
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

View File

@ -33,8 +33,7 @@ declare namespace Foo {
export { defaultProps };
}
declare namespace propTypes {
import bar = PropTypes.bool;
export { bar };
export const bar: PropTypes.Requireable<boolean>;
}
declare namespace defaultProps {
const bar_1: boolean;

View File

@ -4,7 +4,6 @@
// @outDir: ./out
// @declaration: true
// @filename: index.js
// TODO: Fixup
class A {
member = new Q();
}

View File

@ -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
/// <reference path="/.lib/react16.d.ts" />
import React from "react";
import PropTypes from "prop-types"
const TabbedShowLayout = ({
}) => {
return (
<div />
);
};
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 (
<div className="" key="">
ok
</div>
);
};
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 (
<div className="" key="">
ok
</div>
);
};
TabbedShowLayout.defaultProps = {
tabs: "default value"
};
export default TabbedShowLayout;
// @filename: jsDeclarationsReactComponents4.jsx
import React from "react";
const TabbedShowLayout = (/** @type {{className: string}}*/prop) => {
return (
<div className={prop.className} key="">
ok
</div>
);
};
TabbedShowLayout.defaultProps = {
tabs: "default value"
};
export default TabbedShowLayout;
// @filename: jsDeclarationsReactComponents5.jsx
import React from 'react';
import PropTypes from 'prop-types';
function Tree({ allowDropOnRoot }) {
return <div />
}
Tree.propTypes = {
classes: PropTypes.object,
};
Tree.defaultProps = {
classes: {},
parentSource: 'parent_id',
};
export default Tree;