Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ func IsClassElement(node *Node) bool {
return false
}

func isMethodOrAccessor(node *Node) bool {
func IsMethodOrAccessor(node *Node) bool {
switch node.Kind {
case KindMethodDeclaration, KindGetAccessor, KindSetAccessor:
return true
Expand All @@ -580,7 +580,7 @@ func isMethodOrAccessor(node *Node) bool {
}

func IsPrivateIdentifierClassElementDeclaration(node *Node) bool {
return (IsPropertyDeclaration(node) || isMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
return (IsPropertyDeclaration(node) || IsMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
}

func IsObjectLiteralOrClassExpressionMethodOrAccessor(node *Node) bool {
Expand Down
18 changes: 12 additions & 6 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19101,11 +19101,9 @@ func (c *Checker) getSignaturesOfSymbol(symbol *ast.Symbol) []*Signature {
}
// If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters.
// Exclude contextually-typed kinds because we already apply the @type tag to the context, plus applying it here to the initializer would suppress checks that the two are compatible.
if ast.IsFunctionExpressionOrArrowFunction(decl) || ast.IsObjectLiteralMethod(decl) {
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
result = append(result, sig)
continue
}
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
result = append(result, sig)
continue
}
result = append(result, c.getSignatureFromDeclaration(decl))
}
Expand All @@ -19123,6 +19121,14 @@ func (c *Checker) getSignatureFromDeclaration(declaration *ast.Node) *Signature
minArgumentCount := 0
hasThisParameter := false
iife := ast.GetImmediatelyInvokedFunctionExpression(declaration)
isUntypedSignatureInJSFile := iife == nil &&
ast.IsInJSFile(declaration) &&
(ast.IsFunctionExpression(declaration) || ast.IsArrowFunction(declaration) || ast.IsMethodOrAccessor(declaration) || ast.IsFunctionDeclaration(declaration) || ast.IsConstructorDeclaration(declaration)) &&
core.Every(declaration.Parameters(), func(param *ast.Node) bool { return param.Type() == nil }) &&
c.getContextualSignatureForFunctionLikeDeclaration(declaration) == nil
if isUntypedSignatureInJSFile {
flags |= SignatureFlagsIsUntypedSignatureInJSFile
}
for i, param := range declaration.Parameters() {
paramSymbol := param.Symbol()
typeNode := param.Type()
Expand Down Expand Up @@ -19343,7 +19349,7 @@ func (c *Checker) getReturnTypeFromAnnotation(declaration *ast.Node) *Type {
}

func (c *Checker) getSignatureOfFullSignatureType(node *ast.Node) *Signature {
if ast.IsInJSFile(node) && ast.IsFunctionLike(node) && node.FunctionLikeData().FullSignature != nil {
if ast.IsInJSFile(node) && (ast.IsFunctionDeclaration(node) || ast.IsMethodDeclaration(node) || ast.IsFunctionExpressionOrArrowFunction(node)) && node.FunctionLikeData().FullSignature != nil {
return c.getSingleCallSignature(c.getTypeFromTypeNode(node.FunctionLikeData().FullSignature))
}
return nil
Expand Down
21 changes: 14 additions & 7 deletions internal/checker/emitresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,13 +458,20 @@ func (r *emitResolver) IsImplementationOfOverload(node *ast.SignatureDeclaration
// function foo(a: any) { // This is implementation of the overloads
// return a;
// }
return len(signaturesOfSymbol) > 1 ||
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
// e.g.: function foo(a: string): string;
// function foo(a: any) { // This is implementation of the overloads
// return a;
// }
(len(signaturesOfSymbol) == 1 && signaturesOfSymbol[0].declaration != node)
if len(signaturesOfSymbol) > 1 {
return true
}
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
// e.g.: function foo(a: string): string;
// function foo(a: any) { // This is implementation of the overloads
// return a;
// }
if len(signaturesOfSymbol) == 1 {
declaration := signaturesOfSymbol[0].declaration
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition declaration.Flags&ast.NodeFlagsJSDoc == 0 checks if the JSDoc flag is NOT set, but there's no comment explaining why JSDoc-flagged declarations should be excluded from being considered overload implementations. Adding a brief comment would clarify this non-obvious logic.

Suggested change
declaration := signaturesOfSymbol[0].declaration
declaration := signaturesOfSymbol[0].declaration
// JSDoc signatures are not considered overloads, so exclude JSDoc-flagged declarations.

Copilot uses AI. Check for mistakes.
if declaration != node && declaration.Flags&ast.NodeFlagsJSDoc == 0 {
return true
}
}
}
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @param {2} a
*/
export function conflictingParam(a) { return true }
>conflictingParam : (a: 2) => true
>conflictingParam : (a: 1) => true
>a : 2
>true : true

Expand All @@ -15,7 +15,7 @@ export function conflictingParam(a) { return true }
* @return {false}
*/
export function conflictingReturn(b) { return false }
>conflictingReturn : (b: 3) => false
>conflictingReturn : (b: 3) => true
>b : 3
>false : false

Expand All @@ -26,7 +26,7 @@ export function conflictingReturn(b) { return false }
* @return {false}
*/
export function conflictingBoth(d) { return false }
>conflictingBoth : (d: 5) => false
>conflictingBoth : (c: 4) => true
>d : 5
>false : false

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
main.js(3,9): error TS2554: Expected 0 arguments, but got 3.
main.js(5,1): error TS2554: Expected 2 arguments, but got 0.
main.js(6,16): error TS2554: Expected 2 arguments, but got 3.
main.js(6,16): error TS2554: Expected 0-2 arguments, but got 3.


==== main.js (3 errors) ====
==== main.js (2 errors) ====
function allRest() { arguments; }
allRest();
allRest(1, 2, 3);
~~~~~~~
!!! error TS2554: Expected 0 arguments, but got 3.
function someRest(x, y) { arguments; }
someRest(); // x and y are still optional because they are in a JS file
~~~~~~~~
!!! error TS2554: Expected 2 arguments, but got 0.
!!! related TS6210 main.js:4:19: An argument for 'x' was not provided.
someRest(1, 2, 3);
~
!!! error TS2554: Expected 2 arguments, but got 3.
!!! error TS2554: Expected 0-2 arguments, but got 3.

/**
* @param {number} x - a thing
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
a.js(9,7): error TS2554: Expected 1 arguments, but got 3.
a.js(9,7): error TS2554: Expected 0-1 arguments, but got 3.


==== a.js (1 errors) ====
Expand All @@ -12,5 +12,5 @@ a.js(9,7): error TS2554: Expected 1 arguments, but got 3.

f2(1, 2, 3);
~~~~
!!! error TS2554: Expected 1 arguments, but got 3.
!!! error TS2554: Expected 0-1 arguments, but got 3.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
a.js(5,6): error TS2554: Expected 1 arguments, but got 3.
a.js(5,6): error TS2554: Expected 0-1 arguments, but got 3.


==== a.js (1 errors) ====
Expand All @@ -8,5 +8,5 @@ a.js(5,6): error TS2554: Expected 1 arguments, but got 3.

f(1, 2, 3);
~~~~
!!! error TS2554: Expected 1 arguments, but got 3.
!!! error TS2554: Expected 0-1 arguments, but got 3.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
index.js(1,25): error TS7006: Parameter 'f' implicitly has an 'any' type.
index.js(13,29): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f: any]'.
index.js(13,29): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f?: any]'.


==== index.js (2 errors) ====
Expand All @@ -19,6 +19,6 @@ index.js(13,29): error TS2345: Argument of type 'IArguments' is not assignable t
const debuglog = function() {
return format.apply(null, arguments);
~~~~~~~~~
!!! error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f: any]'.
!!! error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f?: any]'.
};

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var k = function (x) { return x }
/** @typedef {(x: 'hi' | 'bye') => 0 | 1 | 2} Argle */
/** @type {Argle} */
function blargle(s) {
>blargle : (s: "bye" | "hi") => 0 | 1 | 2
>blargle : (x: "bye" | "hi") => 0 | 1 | 2
>s : "bye" | "hi"

return 0;
Expand All @@ -57,7 +57,7 @@ function blargle(s) {
var zeroonetwo = blargle('hi')
>zeroonetwo : 0 | 1 | 2
>blargle('hi') : 0 | 1 | 2
>blargle : (s: "bye" | "hi") => 0 | 1 | 2
>blargle : (x: "bye" | "hi") => 0 | 1 | 2
>'hi' : "hi"

/** @typedef {{(s: string): 0 | 1; (b: boolean): 2 | 3 }} Gioconda */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ test.js(1,12): error TS8030: A JSDoc '@type' tag on a function must have a signa
test.js(7,5): error TS2322: Type '(prop: any) => void' is not assignable to type '{ prop: string; }'.
test.js(10,12): error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
test.js(23,12): error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
test.js(27,7): error TS2322: Type '(more: any) => void' is not assignable to type '() => void'.
Target signature provides too few arguments. Expected 1 or more, but got 0.
test.js(30,7): error TS2322: Type '(more: any) => void' is not assignable to type '() => void'.
Target signature provides too few arguments. Expected 1 or more, but got 0.
test.js(33,14): error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.


==== test.js (7 errors) ====
==== test.js (5 errors) ====
/** @type {number} */
~~~~~~
!!! error TS8030: A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.
Expand Down Expand Up @@ -45,15 +41,9 @@ test.js(33,14): error TS8030: A JSDoc '@type' tag on a function must have a sign

/** @type {() => void} */
const variableWithMoreParameters = function (more) {}; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '(more: any) => void' is not assignable to type '() => void'.
!!! error TS2322: Target signature provides too few arguments. Expected 1 or more, but got 0.

/** @type {() => void} */
const arrowWithMoreParameters = (more) => {}; // error
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '(more: any) => void' is not assignable to type '() => void'.
!!! error TS2322: Target signature provides too few arguments. Expected 1 or more, but got 0.

({
/** @type {() => void} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var g = function (prop) {

/** @type {(a: number) => number} */
function add1(a, b) { return a + b; }
>add1 : (a: number, b: any) => number
>add1 : (a: number) => number
>a : number
>b : any
>a + b : any
Expand All @@ -37,7 +37,7 @@ function add2(a, b) { return a + b; }
// TODO: Should be an error since signature doesn't match.
/** @type {(a: number, b: number, c: number) => number} */
function add3(a, b) { return a + b; }
>add3 : (a: number, b: number) => number
>add3 : (a: number, b: number, c: number) => number
>a : number
>b : number
>a + b : number
Expand All @@ -49,7 +49,7 @@ function add3(a, b) { return a + b; }

/** @type {() => void} */
function funcWithMoreParameters(more) {} // error
>funcWithMoreParameters : (more: any) => void
>funcWithMoreParameters : () => void
>more : any

/** @type {() => void} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ class C {

/** @type {(optional?) => void} */
methodWithOptionalParameters() {}
>methodWithOptionalParameters : () => void
>methodWithOptionalParameters : (optional?: any) => void
}

Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
error TS5055: Cannot write file 'jsdocReadonlyDeclarations.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
error TS5102: Option 'outFile' has been removed. Please remove it from your configuration.
jsdocReadonlyDeclarations.js(14,1): error TS2554: Expected 1 arguments, but got 0.


!!! error TS5055: Cannot write file 'jsdocReadonlyDeclarations.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
!!! error TS5102: Option 'outFile' has been removed. Please remove it from your configuration.
==== jsdocReadonlyDeclarations.js (1 errors) ====
==== jsdocReadonlyDeclarations.js (0 errors) ====
class C {
/** @readonly */
x = 6
Expand All @@ -22,9 +21,6 @@ jsdocReadonlyDeclarations.js(14,1): error TS2554: Expected 1 arguments, but got
}
}
new C().x
~~~~~~~
!!! error TS2554: Expected 1 arguments, but got 0.
!!! related TS6210 jsdocReadonlyDeclarations.js:5:17: An argument for 'n' was not provided.

function F() {
/** @readonly */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const f1 = function() {

/** @type {import('./types').M} */
export function f2() {
>f2 : () => void
>f2 : (this: import("/types").Foo) => void

this.test();
>this.test() : any
Expand All @@ -48,7 +48,7 @@ export const f3 = function() {

/** @type {(this: import('./types').Foo) => void} */
export function f4() {
>f4 : () => void
>f4 : (this: import("/types").Foo) => void

this.test();
>this.test() : any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ a.js(13,1): error TS2554: Expected 1 arguments, but got 0.
g() // should error
~
!!! error TS2554: Expected 1 arguments, but got 0.
!!! related TS6210 a.js:5:12: An argument for 's' was not provided.
!!! related TS6210 a.js:4:13: An argument for 's' was not provided.
h()
~
!!! error TS2554: Expected 1 arguments, but got 0.
!!! related TS6210 a.js:8:12: An argument for 's' was not provided.
!!! related TS6210 a.js:7:14: An argument for 's' was not provided.

Loading