mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix js missing type arguments on existing nodes and jsdoc object literal declaration emit
This commit is contained in:
+21
-2
@@ -5503,6 +5503,10 @@ namespace ts {
|
||||
return symbol.declarations && find(symbol.declarations, s => !!getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration)));
|
||||
}
|
||||
|
||||
function getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(existing: TypeNode, type: Type) {
|
||||
return !(getObjectFlags(type) & ObjectFlags.Reference) || !isTypeReferenceNode(existing) || length(existing.typeArguments) >= getMinTypeArgumentCount((type as TypeReference).target.typeParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike `typeToTypeNodeHelper`, this handles setting up the `AllowUniqueESSymbolType` flag
|
||||
* so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym`
|
||||
@@ -5513,7 +5517,7 @@ namespace ts {
|
||||
if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation)) {
|
||||
// try to reuse the existing annotation
|
||||
const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
|
||||
if (getTypeFromTypeNode(existing) === type) {
|
||||
if (getTypeFromTypeNode(existing) === type && getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(existing, type)) {
|
||||
const result = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -5534,7 +5538,7 @@ namespace ts {
|
||||
function serializeReturnTypeForSignature(context: NodeBuilderContext, type: Type, signature: Signature, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) {
|
||||
if (type !== errorType && context.enclosingDeclaration) {
|
||||
const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration);
|
||||
if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type) {
|
||||
if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type && getExistingNodeHasNoTypeParametersOrMatchingTypeParameters(annotation, type)) {
|
||||
const result = serializeExistingTypeNode(context, annotation, includePrivateSymbol, bundled);
|
||||
if (result) {
|
||||
return result;
|
||||
@@ -5575,6 +5579,21 @@ namespace ts {
|
||||
if (isJSDocVariadicType(node)) {
|
||||
return createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols));
|
||||
}
|
||||
if (isJSDocTypeLiteral(node)) {
|
||||
return createTypeLiteralNode(map(node.jsDocPropertyTags, t => {
|
||||
const name = isIdentifier(t.name) ? t.name : t.name.right;
|
||||
const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText);
|
||||
const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined;
|
||||
|
||||
return createPropertySignature(
|
||||
/*modifiers*/ undefined,
|
||||
name,
|
||||
t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? createToken(SyntaxKind.QuestionToken) : undefined,
|
||||
overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || createKeywordTypeNode(SyntaxKind.AnyKeyword),
|
||||
/*initializer*/ undefined
|
||||
);
|
||||
}));
|
||||
}
|
||||
if (isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "") {
|
||||
return setOriginalNode(createKeywordTypeNode(SyntaxKind.AnyKeyword), node);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//// [file.js]
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
function x(x) {}
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
function y(x) {}
|
||||
|
||||
//// [file.js]
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
function x(x) { }
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
function y(x) { }
|
||||
|
||||
|
||||
//// [file.d.ts]
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
declare function x(x: any[]): void;
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
declare function y(x: Promise<any>): void;
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/jsdoc/declarations/file.js ===
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
function x(x) {}
|
||||
>x : Symbol(x, Decl(file.js, 0, 0))
|
||||
>x : Symbol(x, Decl(file.js, 3, 11))
|
||||
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
function y(x) {}
|
||||
>y : Symbol(y, Decl(file.js, 3, 16))
|
||||
>x : Symbol(x, Decl(file.js, 7, 11))
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/jsdoc/declarations/file.js ===
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
function x(x) {}
|
||||
>x : (x: any[]) => void
|
||||
>x : any[]
|
||||
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
function y(x) {}
|
||||
>y : (x: Promise<any>) => void
|
||||
>x : Promise<any>
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//// [file.js]
|
||||
class X {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, code}) {}
|
||||
}
|
||||
|
||||
class Y {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, suberr}) {}
|
||||
}
|
||||
|
||||
|
||||
//// [file.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
class X {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
cancel({ reason, code }) {
|
||||
return __awaiter(this, void 0, void 0, function* () { });
|
||||
}
|
||||
}
|
||||
class Y {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
cancel({ reason, suberr }) {
|
||||
return __awaiter(this, void 0, void 0, function* () { });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [file.d.ts]
|
||||
declare class X {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
cancel({ reason, code }: {
|
||||
reason: string | null;
|
||||
code: string | null;
|
||||
}): Promise<any>;
|
||||
}
|
||||
declare class Y {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
cancel({ reason, suberr }: {
|
||||
reason: string | null;
|
||||
suberr: {
|
||||
reason: string | null;
|
||||
code: string | null;
|
||||
};
|
||||
}): Promise<any>;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
=== tests/cases/conformance/jsdoc/declarations/file.js ===
|
||||
class X {
|
||||
>X : Symbol(X, Decl(file.js, 0, 0))
|
||||
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, code}) {}
|
||||
>cancel : Symbol(X.cancel, Decl(file.js, 0, 9))
|
||||
>reason : Symbol(reason, Decl(file.js, 8, 18))
|
||||
>code : Symbol(code, Decl(file.js, 8, 25))
|
||||
}
|
||||
|
||||
class Y {
|
||||
>Y : Symbol(Y, Decl(file.js, 9, 1))
|
||||
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, suberr}) {}
|
||||
>cancel : Symbol(Y.cancel, Decl(file.js, 11, 9))
|
||||
>reason : Symbol(reason, Decl(file.js, 21, 18))
|
||||
>suberr : Symbol(suberr, Decl(file.js, 21, 25))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
=== tests/cases/conformance/jsdoc/declarations/file.js ===
|
||||
class X {
|
||||
>X : X
|
||||
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, code}) {}
|
||||
>cancel : ({ reason, code }: { reason: string | null; code: string | null;}) => Promise<any>
|
||||
>reason : string
|
||||
>code : string
|
||||
}
|
||||
|
||||
class Y {
|
||||
>Y : Y
|
||||
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, suberr}) {}
|
||||
>cancel : ({ reason, suberr }: { reason: string | null; suberr: { reason: string | null; code: string | null; };}) => Promise<any>
|
||||
>reason : string
|
||||
>suberr : { reason: string; code: string; }
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ var numberArray = [5];
|
||||
* @return {Array}
|
||||
*/
|
||||
function returnAnyArray(arr) {
|
||||
>returnAnyArray : (arr: Array) => Array
|
||||
>returnAnyArray : (arr: any[]) => any[]
|
||||
>arr : any[]
|
||||
|
||||
return arr;
|
||||
@@ -46,7 +46,7 @@ var numberPromise = Promise.resolve(5);
|
||||
* @return {Promise}
|
||||
*/
|
||||
function returnAnyPromise(pr) {
|
||||
>returnAnyPromise : (pr: Promise) => Promise
|
||||
>returnAnyPromise : (pr: Promise<any>) => Promise<any>
|
||||
>pr : Promise<any>
|
||||
|
||||
return pr;
|
||||
|
||||
@@ -16,7 +16,7 @@ var numberArray = [5];
|
||||
* @return {Array}
|
||||
*/
|
||||
function returnNotAnyArray(arr) {
|
||||
>returnNotAnyArray : (arr: Array) => Array
|
||||
>returnNotAnyArray : (arr: any[]) => any[]
|
||||
>arr : any[]
|
||||
|
||||
return arr;
|
||||
@@ -46,7 +46,7 @@ var numberPromise = Promise.resolve(5);
|
||||
* @return {Promise}
|
||||
*/
|
||||
function returnNotAnyPromise(pr) {
|
||||
>returnNotAnyPromise : (pr: Promise) => Promise
|
||||
>returnNotAnyPromise : (pr: Promise<any>) => Promise<any>
|
||||
>pr : Promise<any>
|
||||
|
||||
return pr;
|
||||
|
||||
@@ -5,6 +5,6 @@ class C {}
|
||||
|
||||
/** @param {C} p */
|
||||
function f(p) {}
|
||||
>f : (p: C) => void
|
||||
>f : (p: C<any>) => void
|
||||
>p : C<any>
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ function good4({a, b}) {}
|
||||
* @param {string} x
|
||||
*/
|
||||
function good5({a, b}, x) {}
|
||||
>good5 : ({ a, b }: * @param {string} obj.a - this is like the saddest way to specify a type * @param {string} obj.b - but it sure does allow a lot of documentation, x: string) => void
|
||||
>good5 : ({ a, b }: { a: string; b: string;}, x: string) => void
|
||||
>a : string
|
||||
>b : string
|
||||
>x : string
|
||||
@@ -63,7 +63,7 @@ function good5({a, b}, x) {}
|
||||
* @param {string} OBJECTION.d - meh
|
||||
*/
|
||||
function good6({a, b}, {c, d}) {}
|
||||
>good6 : ({ a, b }: * @param {string} obj.a * @param {string} obj.b - but it sure does allow a lot of documentation, { c, d }: * @param {string} OBJECTION.c * @param {string} OBJECTION.d - meh) => void
|
||||
>good6 : ({ a, b }: { a: string; b: string;}, { c, d }: { c: string; d: string;}) => void
|
||||
>a : string
|
||||
>b : string
|
||||
>c : string
|
||||
@@ -77,7 +77,7 @@ function good6({a, b}, {c, d}) {}
|
||||
* @param {string} y
|
||||
*/
|
||||
function good7(x, {a, b}, y) {}
|
||||
>good7 : (x: number, { a, b }: * @param {string} obj.a * @param {string} obj.b, y: string) => void
|
||||
>good7 : (x: number, { a, b }: { a: string; b: string;}, y: string) => void
|
||||
>x : number
|
||||
>a : string
|
||||
>b : string
|
||||
@@ -89,7 +89,7 @@ function good7(x, {a, b}, y) {}
|
||||
* @param {string} obj.b
|
||||
*/
|
||||
function good8({a, b}) {}
|
||||
>good8 : ({ a, b }: * @param {string} obj.a * @param {string} obj.b) => void
|
||||
>good8 : ({ a, b }: { a: string; b: string;}) => void
|
||||
>a : string
|
||||
>b : string
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ normal(12);
|
||||
* @param {string} [opts1.w="hi"] doc5
|
||||
*/
|
||||
function foo1(opts1) {
|
||||
>foo1 : (opts1: * @param {string} opts1.x doc2 * @param {string=} opts1.y doc3 * @param {string} [opts1.z] doc4 * @param {string} [opts1.w] doc5) => void
|
||||
>foo1 : (opts1: { x: string; y?: string | undefined; z: string; w: string;}) => void
|
||||
>opts1 : { x: string; y?: string | undefined; z?: string; w?: string; }
|
||||
|
||||
opts1.x;
|
||||
@@ -45,7 +45,7 @@ foo1({x: 'abc'});
|
||||
* @param {string=} opts2[].anotherY
|
||||
*/
|
||||
function foo2(/** @param opts2 bad idea theatre! */opts2) {
|
||||
>foo2 : (opts2: * @param {string} opts2.anotherX * @param {string=} opts2.anotherY) => void
|
||||
>foo2 : (opts2: { anotherX: string; anotherY?: string | undefined;}) => void
|
||||
>opts2 : { anotherX: string; anotherY?: string | undefined; }[]
|
||||
|
||||
opts2[0].anotherX;
|
||||
@@ -69,7 +69,7 @@ foo2([{anotherX: "world"}]);
|
||||
* @param {string} opts3.x
|
||||
*/
|
||||
function foo3(opts3) {
|
||||
>foo3 : (opts3: * @param {string} opts3.x) => void
|
||||
>foo3 : (opts3: { x: string;}) => void
|
||||
>opts3 : { x: string; }
|
||||
|
||||
opts3.x;
|
||||
@@ -92,7 +92,7 @@ foo3({x: 'abc'});
|
||||
* @param {string} [opts4[].w="hi"]
|
||||
*/
|
||||
function foo4(opts4) {
|
||||
>foo4 : (opts4: * @param {string} opts4.x * @param {string=} opts4.y * @param {string} [opts4.z] * @param {string} [opts4.w]) => void
|
||||
>foo4 : (opts4: { x: string; y?: string | undefined; z: string; w: string;}) => void
|
||||
>opts4 : { x: string; y?: string | undefined; z?: string; w?: string; }[]
|
||||
|
||||
opts4[0].x;
|
||||
@@ -122,7 +122,7 @@ foo4([{ x: 'hi' }]);
|
||||
* @param {number} opts5[].unnest - Here we are almost all the way back at the beginning.
|
||||
*/
|
||||
function foo5(opts5) {
|
||||
>foo5 : (opts5: * @param {string} opts5.help - (This one is just normal) * @param { * @param {string} opts5.what.a - (Another normal one) * @param { * @param {string} opts5.what.bad.idea - I don't think you can get back out of this level... * @param {boolean} opts5.what.bad.oh - Oh ... that's how you do it.} opts5.what.bad - Now we're nesting inside a nested type} opts5.what - Look at us go! Here's the first nest! * @param {number} opts5.unnest - Here we are almost all the way back at the beginning.) => void
|
||||
>foo5 : (opts5: { help: string; what: { a: string; bad: { idea: string; oh: boolean; }; }; unnest: number;}) => void
|
||||
>opts5 : { help: string; what: { a: string; bad: { idea: string; oh: boolean; }[]; }; unnest: number; }[]
|
||||
|
||||
opts5[0].what.bad[0].idea;
|
||||
|
||||
@@ -26,13 +26,13 @@ function Zet(t) {
|
||||
* @param {T} o.nested
|
||||
*/
|
||||
Zet.prototype.add = function(v, o) {
|
||||
>Zet.prototype.add = function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: * @param {T} o.nested) => T
|
||||
>Zet.prototype.add = function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: { nested: T; }) => T
|
||||
>Zet.prototype.add : any
|
||||
>Zet.prototype : any
|
||||
>Zet : typeof Zet
|
||||
>prototype : any
|
||||
>add : any
|
||||
>function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: * @param {T} o.nested) => T
|
||||
>function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: { nested: T; }) => T
|
||||
>v : T
|
||||
>o : { nested: T; }
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: es5
|
||||
// @outDir: ./out
|
||||
// @declaration: true
|
||||
// @filename: file.js
|
||||
/**
|
||||
* @param {Array} x
|
||||
*/
|
||||
function x(x) {}
|
||||
/**
|
||||
* @param {Promise} x
|
||||
*/
|
||||
function y(x) {}
|
||||
@@ -0,0 +1,29 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: es6
|
||||
// @outDir: ./out
|
||||
// @declaration: true
|
||||
// @filename: file.js
|
||||
class X {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, code}) {}
|
||||
}
|
||||
|
||||
class Y {
|
||||
/**
|
||||
* Cancels the request, sending a cancellation to the other party
|
||||
* @param {Object} error __auto_generated__
|
||||
* @param {string?} error.reason the error reason to send the cancellation with
|
||||
* @param {Object} error.suberr
|
||||
* @param {string?} error.suberr.reason the error reason to send the cancellation with
|
||||
* @param {string?} error.suberr.code the error code to send the cancellation with
|
||||
* @returns {Promise.<*>} resolves when the event has been sent.
|
||||
*/
|
||||
async cancel({reason, suberr}) {}
|
||||
}
|
||||
Reference in New Issue
Block a user