mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-03 09:19:49 -06:00
Fix type when annotated with a JSDoc function type (#22692)
* Fix type when annotated with a JSDoc function type Previously, 1. A variable annotated with a JSDoc function type would not require all its parameters to be provided. This should only apply to functions without a type annotation. 2. A parameter in a function with a JSDoc function type annotation would still have the type 'any'. 3. Two `var` declarations in a Typescript and Javascript file, respectively, would error even when they had identical function types. * Update baselines and add constructor test * Handle ConstructorType too * Add test:method sig inside literal type * Contextually type parameters by parent sig's JSDoc Instead of a syntactic check in getJSDocTag * Remove redundant check:isUntypedSignatureInJSFile * Positive check for value signatures Instead of excluding type signatures piecemeal.
This commit is contained in:
parent
d88041fc0a
commit
b56093f3ac
@ -6691,7 +6691,11 @@ namespace ts {
|
||||
let hasThisParameter: boolean;
|
||||
const iife = getImmediatelyInvokedFunctionExpression(declaration);
|
||||
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
||||
const isUntypedSignatureInJSFile = !iife && !isJSConstructSignature && isInJavaScriptFile(declaration) && !hasJSDocParameterTags(declaration);
|
||||
const isUntypedSignatureInJSFile = !iife &&
|
||||
isInJavaScriptFile(declaration) &&
|
||||
isValueSignatureDeclaration(declaration) &&
|
||||
!hasJSDocParameterTags(declaration) &&
|
||||
!getJSDocType(declaration);
|
||||
|
||||
// If this is a JSDoc construct signature, then skip the first parameter in the
|
||||
// parameter list. The first parameter represents the return type of the construct
|
||||
@ -9100,7 +9104,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
|
||||
return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
|
||||
return (isInJavaScriptFile(func) && isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) &&
|
||||
isContextSensitiveFunctionLikeDeclaration(func);
|
||||
}
|
||||
|
||||
function getTypeWithoutSignatures(type: Type): Type {
|
||||
@ -14168,49 +14173,49 @@ namespace ts {
|
||||
// Return contextual type of parameter or undefined if no contextual type is available
|
||||
function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type | undefined {
|
||||
const func = parameter.parent;
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
const iife = getImmediatelyInvokedFunctionExpression(func);
|
||||
if (iife && iife.arguments) {
|
||||
const indexOfParameter = func.parameters.indexOf(parameter);
|
||||
if (parameter.dotDotDotToken) {
|
||||
const restTypes: Type[] = [];
|
||||
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
|
||||
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
|
||||
}
|
||||
return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
|
||||
if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
return undefined;
|
||||
}
|
||||
const iife = getImmediatelyInvokedFunctionExpression(func);
|
||||
if (iife && iife.arguments) {
|
||||
const indexOfParameter = func.parameters.indexOf(parameter);
|
||||
if (parameter.dotDotDotToken) {
|
||||
const restTypes: Type[] = [];
|
||||
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
|
||||
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
|
||||
}
|
||||
const links = getNodeLinks(iife);
|
||||
const cached = links.resolvedSignature;
|
||||
links.resolvedSignature = anySignature;
|
||||
const type = indexOfParameter < iife.arguments.length ?
|
||||
getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
|
||||
parameter.initializer ? undefined : undefinedWideningType;
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
|
||||
}
|
||||
const links = getNodeLinks(iife);
|
||||
const cached = links.resolvedSignature;
|
||||
links.resolvedSignature = anySignature;
|
||||
const type = indexOfParameter < iife.arguments.length ?
|
||||
getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
|
||||
parameter.initializer ? undefined : undefinedWideningType;
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
}
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
const funcHasRestParameters = hasRestParameter(func);
|
||||
const len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
|
||||
let indexOfParameter = func.parameters.indexOf(parameter);
|
||||
if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) {
|
||||
Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`.
|
||||
indexOfParameter -= 1;
|
||||
}
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
const funcHasRestParameters = hasRestParameter(func);
|
||||
const len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
|
||||
let indexOfParameter = func.parameters.indexOf(parameter);
|
||||
if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) {
|
||||
Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`.
|
||||
indexOfParameter -= 1;
|
||||
}
|
||||
|
||||
if (indexOfParameter < len) {
|
||||
return getTypeAtPosition(contextualSignature, indexOfParameter);
|
||||
}
|
||||
if (indexOfParameter < len) {
|
||||
return getTypeAtPosition(contextualSignature, indexOfParameter);
|
||||
}
|
||||
|
||||
// If last parameter is contextually rest parameter get its type
|
||||
if (funcHasRestParameters &&
|
||||
indexOfParameter === (func.parameters.length - 1) &&
|
||||
isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
|
||||
return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters));
|
||||
}
|
||||
// If last parameter is contextually rest parameter get its type
|
||||
if (funcHasRestParameters &&
|
||||
indexOfParameter === (func.parameters.length - 1) &&
|
||||
isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
|
||||
return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters));
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// In a variable, parameter or property declaration with a type annotation,
|
||||
@ -14773,7 +14778,16 @@ namespace ts {
|
||||
// union type of return types from these signatures
|
||||
function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
const type = getContextualTypeForFunctionLikeDeclaration(node);
|
||||
let type: Type;
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const jsdoc = getJSDocType(node);
|
||||
if (jsdoc) {
|
||||
type = getTypeFromTypeNode(jsdoc);
|
||||
}
|
||||
}
|
||||
if (!type) {
|
||||
type = getContextualTypeForFunctionLikeDeclaration(node);
|
||||
}
|
||||
if (!type) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -1958,6 +1958,18 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export type ValueSignatureDeclaration =
|
||||
| FunctionDeclaration
|
||||
| MethodDeclaration
|
||||
| ConstructorDeclaration
|
||||
| AccessorDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction;
|
||||
|
||||
export function isValueSignatureDeclaration(node: Node): node is ValueSignatureDeclaration {
|
||||
return isFunctionExpression(node) || isArrowFunction(node) || isMethodOrAccessor(node) || isFunctionDeclaration(node) || isConstructorDeclaration(node);
|
||||
}
|
||||
|
||||
function walkUp(node: Node, kind: SyntaxKind) {
|
||||
while (node && node.kind === kind) {
|
||||
node = node.parent;
|
||||
|
||||
@ -20,12 +20,12 @@ const obj = {
|
||||
|
||||
/** @type {function(number): number} */
|
||||
method1(n1) {
|
||||
>method1 : (n1: any) => any
|
||||
>n1 : any
|
||||
>method1 : (n1: number) => number
|
||||
>n1 : number
|
||||
|
||||
return n1 + 42;
|
||||
>n1 + 42 : any
|
||||
>n1 : any
|
||||
>n1 + 42 : number
|
||||
>n1 : number
|
||||
>42 : 42
|
||||
|
||||
},
|
||||
@ -44,10 +44,10 @@ const obj = {
|
||||
/** @type {function(number): number} */
|
||||
arrowFunc: (num) => num + 42
|
||||
>arrowFunc : (arg0: number) => number
|
||||
>(num) => num + 42 : (num: any) => any
|
||||
>num : any
|
||||
>num + 42 : any
|
||||
>num : any
|
||||
>(num) => num + 42 : (num: number) => number
|
||||
>num : number
|
||||
>num + 42 : number
|
||||
>num : number
|
||||
>42 : 42
|
||||
}
|
||||
obj.foo = 'string'
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
tests/cases/conformance/jsdoc/0.js(5,3): error TS2322: Type 'number' is not assignable to type 'string | undefined'.
|
||||
tests/cases/conformance/jsdoc/0.js(7,3): error TS2322: Type '(n1: any) => string' is not assignable to type '(arg0: number) => number'.
|
||||
tests/cases/conformance/jsdoc/0.js(7,3): error TS2322: Type '(n1: number) => string' is not assignable to type '(arg0: number) => number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(11,3): error TS2322: Type '(n1: any) => string' is not assignable to type '(arg0: number) => number'.
|
||||
tests/cases/conformance/jsdoc/0.js(11,3): error TS2322: Type '(n1: number) => string' is not assignable to type '(arg0: number) => number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(13,3): error TS2322: Type '(num?: string) => string' is not assignable to type '(arg0: number) => number'.
|
||||
Types of parameters 'num' and 'arg0' are incompatible.
|
||||
Type 'number' is not assignable to type 'string | undefined'.
|
||||
tests/cases/conformance/jsdoc/0.js(13,15): error TS2322: Type '"0"' is not assignable to type 'number'.
|
||||
tests/cases/conformance/jsdoc/0.js(15,3): error TS2322: Type 'undefined' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/0.js(19,5): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/0.js(22,22): error TS2345: Argument of type '"0"' is not assignable to parameter of type 'number'.
|
||||
@ -22,21 +20,19 @@ tests/cases/conformance/jsdoc/0.js(22,22): error TS2345: Argument of type '"0"'
|
||||
/** @type {function(number): number} */
|
||||
method1(n1) {
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '(n1: any) => string' is not assignable to type '(arg0: number) => number'.
|
||||
!!! error TS2322: Type '(n1: number) => string' is not assignable to type '(arg0: number) => number'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
return "42";
|
||||
},
|
||||
/** @type {function(number): number} */
|
||||
method2: (n1) => "lol",
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(n1: any) => string' is not assignable to type '(arg0: number) => number'.
|
||||
!!! error TS2322: Type '(n1: number) => string' is not assignable to type '(arg0: number) => number'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
/** @type {function(number): number} */
|
||||
arrowFunc: (num="0") => num + 42,
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '(num?: string) => string' is not assignable to type '(arg0: number) => number'.
|
||||
!!! error TS2322: Types of parameters 'num' and 'arg0' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string | undefined'.
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '"0"' is not assignable to type 'number'.
|
||||
/** @type {string} */
|
||||
lol
|
||||
~~~
|
||||
|
||||
@ -14,8 +14,8 @@ const obj = {
|
||||
|
||||
/** @type {function(number): number} */
|
||||
method1(n1) {
|
||||
>method1 : (n1: any) => string
|
||||
>n1 : any
|
||||
>method1 : (n1: number) => string
|
||||
>n1 : number
|
||||
|
||||
return "42";
|
||||
>"42" : "42"
|
||||
@ -24,18 +24,18 @@ const obj = {
|
||||
/** @type {function(number): number} */
|
||||
method2: (n1) => "lol",
|
||||
>method2 : (arg0: number) => number
|
||||
>(n1) => "lol" : (n1: any) => string
|
||||
>n1 : any
|
||||
>(n1) => "lol" : (n1: number) => string
|
||||
>n1 : number
|
||||
>"lol" : "lol"
|
||||
|
||||
/** @type {function(number): number} */
|
||||
arrowFunc: (num="0") => num + 42,
|
||||
>arrowFunc : (arg0: number) => number
|
||||
>(num="0") => num + 42 : (num?: string) => string
|
||||
>num : string
|
||||
>(num="0") => num + 42 : (num?: number) => number
|
||||
>num : number
|
||||
>"0" : "0"
|
||||
>num + 42 : string
|
||||
>num : string
|
||||
>num + 42 : number
|
||||
>num : number
|
||||
>42 : 42
|
||||
|
||||
/** @type {string} */
|
||||
|
||||
@ -60,6 +60,12 @@ var obj;
|
||||
|
||||
/** @type {Function} */
|
||||
var Func;
|
||||
|
||||
/** @type {(s: string) => number} */
|
||||
var f;
|
||||
|
||||
/** @type {new (s: string) => { s: string }} */
|
||||
var ctor;
|
||||
|
||||
//// [b.ts]
|
||||
var S: string;
|
||||
@ -82,6 +88,8 @@ var nullable: number | null;
|
||||
var Obj: any;
|
||||
var obj: any;
|
||||
var Func: Function;
|
||||
var f: (s: string) => number;
|
||||
var ctor: new (s: string) => { s: string };
|
||||
|
||||
|
||||
//// [a.js]
|
||||
@ -125,6 +133,10 @@ var Obj;
|
||||
var obj;
|
||||
/** @type {Function} */
|
||||
var Func;
|
||||
/** @type {(s: string) => number} */
|
||||
var f;
|
||||
/** @type {new (s: string) => { s: string }} */
|
||||
var ctor;
|
||||
//// [b.js]
|
||||
var S;
|
||||
var s;
|
||||
@ -146,3 +158,5 @@ var nullable;
|
||||
var Obj;
|
||||
var obj;
|
||||
var Func;
|
||||
var f;
|
||||
var ctor;
|
||||
|
||||
@ -79,6 +79,14 @@ var obj;
|
||||
var Func;
|
||||
>Func : Symbol(Func, Decl(a.js, 58, 3), Decl(b.ts, 19, 3))
|
||||
|
||||
/** @type {(s: string) => number} */
|
||||
var f;
|
||||
>f : Symbol(f, Decl(a.js, 61, 3), Decl(b.ts, 20, 3))
|
||||
|
||||
/** @type {new (s: string) => { s: string }} */
|
||||
var ctor;
|
||||
>ctor : Symbol(ctor, Decl(a.js, 64, 3), Decl(b.ts, 21, 3))
|
||||
|
||||
=== tests/cases/conformance/jsdoc/b.ts ===
|
||||
var S: string;
|
||||
>S : Symbol(S, Decl(a.js, 1, 3), Decl(b.ts, 0, 3))
|
||||
@ -143,3 +151,12 @@ var Func: Function;
|
||||
>Func : Symbol(Func, Decl(a.js, 58, 3), Decl(b.ts, 19, 3))
|
||||
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
var f: (s: string) => number;
|
||||
>f : Symbol(f, Decl(a.js, 61, 3), Decl(b.ts, 20, 3))
|
||||
>s : Symbol(s, Decl(b.ts, 20, 8))
|
||||
|
||||
var ctor: new (s: string) => { s: string };
|
||||
>ctor : Symbol(ctor, Decl(a.js, 64, 3), Decl(b.ts, 21, 3))
|
||||
>s : Symbol(s, Decl(b.ts, 21, 15))
|
||||
>s : Symbol(s, Decl(b.ts, 21, 30))
|
||||
|
||||
|
||||
@ -79,6 +79,14 @@ var obj;
|
||||
var Func;
|
||||
>Func : Function
|
||||
|
||||
/** @type {(s: string) => number} */
|
||||
var f;
|
||||
>f : (s: string) => number
|
||||
|
||||
/** @type {new (s: string) => { s: string }} */
|
||||
var ctor;
|
||||
>ctor : new (s: string) => { s: string; }
|
||||
|
||||
=== tests/cases/conformance/jsdoc/b.ts ===
|
||||
var S: string;
|
||||
>S : string
|
||||
@ -146,3 +154,12 @@ var Func: Function;
|
||||
>Func : Function
|
||||
>Function : Function
|
||||
|
||||
var f: (s: string) => number;
|
||||
>f : (s: string) => number
|
||||
>s : string
|
||||
|
||||
var ctor: new (s: string) => { s: string };
|
||||
>ctor : new (s: string) => { s: string; }
|
||||
>s : string
|
||||
>s : string
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
tests/cases/conformance/jsdoc/a.js(3,5): error TS2322: Type '1' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/a.js(7,5): error TS2322: Type '1' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/a.js (2 errors) ====
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
value = 1 // should error
|
||||
~~~~~
|
||||
!!! error TS2322: Type '1' is not assignable to type 'string'.
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
s = 1 // Should error
|
||||
~
|
||||
!!! error TS2322: Type '1' is not assignable to type 'string'.
|
||||
}
|
||||
|
||||
19
tests/baselines/reference/jsdocTypeTagParameterType.symbols
Normal file
19
tests/baselines/reference/jsdocTypeTagParameterType.symbols
Normal file
@ -0,0 +1,19 @@
|
||||
=== tests/cases/conformance/jsdoc/a.js ===
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
>f : Symbol(f, Decl(a.js, 1, 5))
|
||||
>value : Symbol(value, Decl(a.js, 1, 11))
|
||||
|
||||
value = 1 // should error
|
||||
>value : Symbol(value, Decl(a.js, 1, 11))
|
||||
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
>g : Symbol(g, Decl(a.js, 3, 2))
|
||||
>s : Symbol(s, Decl(a.js, 5, 11))
|
||||
|
||||
s = 1 // Should error
|
||||
>s : Symbol(s, Decl(a.js, 5, 11))
|
||||
}
|
||||
|
||||
24
tests/baselines/reference/jsdocTypeTagParameterType.types
Normal file
24
tests/baselines/reference/jsdocTypeTagParameterType.types
Normal file
@ -0,0 +1,24 @@
|
||||
=== tests/cases/conformance/jsdoc/a.js ===
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
>f : (arg0: string) => void
|
||||
>(value) => { value = 1 // should error} : (value: string) => void
|
||||
>value : string
|
||||
|
||||
value = 1 // should error
|
||||
>value = 1 : 1
|
||||
>value : string
|
||||
>1 : 1
|
||||
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
>g : (s: string) => void
|
||||
>s : string
|
||||
|
||||
s = 1 // Should error
|
||||
>s = 1 : 1
|
||||
>s : string
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
tests/cases/conformance/jsdoc/a.js(11,1): error TS2554: Expected 1 arguments, but got 0.
|
||||
tests/cases/conformance/jsdoc/a.js(12,1): error TS2554: Expected 1 arguments, but got 0.
|
||||
tests/cases/conformance/jsdoc/a.js(13,1): error TS2554: Expected 1 arguments, but got 0.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/a.js (3 errors) ====
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
}
|
||||
/** @type {{(s: string): void}} */
|
||||
function h(s) {
|
||||
}
|
||||
|
||||
f() // should error
|
||||
~~~
|
||||
!!! error TS2554: Expected 1 arguments, but got 0.
|
||||
g() // should error
|
||||
~~~
|
||||
!!! error TS2554: Expected 1 arguments, but got 0.
|
||||
h()
|
||||
~~~
|
||||
!!! error TS2554: Expected 1 arguments, but got 0.
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
=== tests/cases/conformance/jsdoc/a.js ===
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
>f : Symbol(f, Decl(a.js, 1, 5))
|
||||
>value : Symbol(value, Decl(a.js, 1, 11))
|
||||
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
>g : Symbol(g, Decl(a.js, 2, 2))
|
||||
>s : Symbol(s, Decl(a.js, 4, 11))
|
||||
}
|
||||
/** @type {{(s: string): void}} */
|
||||
function h(s) {
|
||||
>h : Symbol(h, Decl(a.js, 5, 1))
|
||||
>s : Symbol(s, Decl(a.js, 7, 11))
|
||||
}
|
||||
|
||||
f() // should error
|
||||
>f : Symbol(f, Decl(a.js, 1, 5))
|
||||
|
||||
g() // should error
|
||||
>g : Symbol(g, Decl(a.js, 2, 2))
|
||||
|
||||
h()
|
||||
>h : Symbol(h, Decl(a.js, 5, 1))
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
=== tests/cases/conformance/jsdoc/a.js ===
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
>f : (arg0: string) => void
|
||||
>(value) => {} : (value: string) => void
|
||||
>value : string
|
||||
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
>g : (s: string) => void
|
||||
>s : string
|
||||
}
|
||||
/** @type {{(s: string): void}} */
|
||||
function h(s) {
|
||||
>h : (s: string) => void
|
||||
>s : string
|
||||
}
|
||||
|
||||
f() // should error
|
||||
>f() : void
|
||||
>f : (arg0: string) => void
|
||||
|
||||
g() // should error
|
||||
>g() : void
|
||||
>g : (s: string) => void
|
||||
|
||||
h()
|
||||
>h() : void
|
||||
>h : (s: string) => void
|
||||
|
||||
@ -63,6 +63,12 @@ var obj;
|
||||
/** @type {Function} */
|
||||
var Func;
|
||||
|
||||
/** @type {(s: string) => number} */
|
||||
var f;
|
||||
|
||||
/** @type {new (s: string) => { s: string }} */
|
||||
var ctor;
|
||||
|
||||
// @filename: b.ts
|
||||
var S: string;
|
||||
var s: string;
|
||||
@ -84,3 +90,5 @@ var nullable: number | null;
|
||||
var Obj: any;
|
||||
var obj: any;
|
||||
var Func: Function;
|
||||
var f: (s: string) => number;
|
||||
var ctor: new (s: string) => { s: string };
|
||||
|
||||
15
tests/cases/conformance/jsdoc/jsdocTypeTagParameterType.ts
Normal file
15
tests/cases/conformance/jsdoc/jsdocTypeTagParameterType.ts
Normal file
@ -0,0 +1,15 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @strict: true
|
||||
// @noImplicitAny: true
|
||||
// @Filename: a.js
|
||||
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
value = 1 // should error
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
s = 1 // Should error
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @strict: true
|
||||
// @noImplicitAny: true
|
||||
// @Filename: a.js
|
||||
|
||||
/** @type {function(string): void} */
|
||||
const f = (value) => {
|
||||
};
|
||||
/** @type {(s: string) => void} */
|
||||
function g(s) {
|
||||
}
|
||||
/** @type {{(s: string): void}} */
|
||||
function h(s) {
|
||||
}
|
||||
|
||||
f() // should error
|
||||
g() // should error
|
||||
h()
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
verify.codeFix({
|
||||
description: "Annotate with type from JSDoc",
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`/** @type {function(*, ...number, ...boolean): void} */
|
||||
var x: (arg0: any, arg1: number[], ...rest: boolean[]) => void = (x, ys, ...zs) => { };`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user