Skip to content

Commit bf70757

Browse files
authored
Several fixes to JS typing of functions and methods (#1960)
1 parent f0ca632 commit bf70757

File tree

38 files changed

+105
-448
lines changed

38 files changed

+105
-448
lines changed

internal/ast/utilities.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ func IsClassElement(node *Node) bool {
571571
return false
572572
}
573573

574-
func isMethodOrAccessor(node *Node) bool {
574+
func IsMethodOrAccessor(node *Node) bool {
575575
switch node.Kind {
576576
case KindMethodDeclaration, KindGetAccessor, KindSetAccessor:
577577
return true
@@ -580,7 +580,7 @@ func isMethodOrAccessor(node *Node) bool {
580580
}
581581

582582
func IsPrivateIdentifierClassElementDeclaration(node *Node) bool {
583-
return (IsPropertyDeclaration(node) || isMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
583+
return (IsPropertyDeclaration(node) || IsMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
584584
}
585585

586586
func IsObjectLiteralOrClassExpressionMethodOrAccessor(node *Node) bool {

internal/checker/checker.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19101,11 +19101,9 @@ func (c *Checker) getSignaturesOfSymbol(symbol *ast.Symbol) []*Signature {
1910119101
}
1910219102
// If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters.
1910319103
// 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.
19104-
if ast.IsFunctionExpressionOrArrowFunction(decl) || ast.IsObjectLiteralMethod(decl) {
19105-
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
19106-
result = append(result, sig)
19107-
continue
19108-
}
19104+
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
19105+
result = append(result, sig)
19106+
continue
1910919107
}
1911019108
result = append(result, c.getSignatureFromDeclaration(decl))
1911119109
}
@@ -19123,6 +19121,14 @@ func (c *Checker) getSignatureFromDeclaration(declaration *ast.Node) *Signature
1912319121
minArgumentCount := 0
1912419122
hasThisParameter := false
1912519123
iife := ast.GetImmediatelyInvokedFunctionExpression(declaration)
19124+
isUntypedSignatureInJSFile := iife == nil &&
19125+
ast.IsInJSFile(declaration) &&
19126+
(ast.IsFunctionExpression(declaration) || ast.IsArrowFunction(declaration) || ast.IsMethodOrAccessor(declaration) || ast.IsFunctionDeclaration(declaration) || ast.IsConstructorDeclaration(declaration)) &&
19127+
core.Every(declaration.Parameters(), func(param *ast.Node) bool { return param.Type() == nil }) &&
19128+
c.getContextualType(declaration, ContextFlagsSignature) == nil
19129+
if isUntypedSignatureInJSFile {
19130+
flags |= SignatureFlagsIsUntypedSignatureInJSFile
19131+
}
1912619132
for i, param := range declaration.Parameters() {
1912719133
paramSymbol := param.Symbol()
1912819134
typeNode := param.Type()
@@ -19343,7 +19349,7 @@ func (c *Checker) getReturnTypeFromAnnotation(declaration *ast.Node) *Type {
1934319349
}
1934419350

1934519351
func (c *Checker) getSignatureOfFullSignatureType(node *ast.Node) *Signature {
19346-
if ast.IsInJSFile(node) && ast.IsFunctionLike(node) && node.FunctionLikeData().FullSignature != nil {
19352+
if ast.IsInJSFile(node) && (ast.IsFunctionDeclaration(node) || ast.IsMethodDeclaration(node) || ast.IsFunctionExpressionOrArrowFunction(node)) && node.FunctionLikeData().FullSignature != nil {
1934719353
return c.getSingleCallSignature(c.getTypeFromTypeNode(node.FunctionLikeData().FullSignature))
1934819354
}
1934919355
return nil

internal/checker/emitresolver.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,20 @@ func (r *emitResolver) IsImplementationOfOverload(node *ast.SignatureDeclaration
458458
// function foo(a: any) { // This is implementation of the overloads
459459
// return a;
460460
// }
461-
return len(signaturesOfSymbol) > 1 ||
462-
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
463-
// e.g.: function foo(a: string): string;
464-
// function foo(a: any) { // This is implementation of the overloads
465-
// return a;
466-
// }
467-
(len(signaturesOfSymbol) == 1 && signaturesOfSymbol[0].declaration != node)
461+
if len(signaturesOfSymbol) > 1 {
462+
return true
463+
}
464+
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
465+
// e.g.: function foo(a: string): string;
466+
// function foo(a: any) { // This is implementation of the overloads
467+
// return a;
468+
// }
469+
if len(signaturesOfSymbol) == 1 {
470+
declaration := signaturesOfSymbol[0].declaration
471+
if declaration != node && declaration.Flags&ast.NodeFlagsJSDoc == 0 {
472+
return true
473+
}
474+
}
468475
}
469476
return false
470477
}

testdata/baselines/reference/conformance/jsdocTypeParameterTagConflict.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @param {2} a
77
*/
88
export function conflictingParam(a) { return true }
9-
>conflictingParam : (a: 2) => true
9+
>conflictingParam : (a: 1) => true
1010
>a : 2
1111
>true : true
1212

@@ -15,7 +15,7 @@ export function conflictingParam(a) { return true }
1515
* @return {false}
1616
*/
1717
export function conflictingReturn(b) { return false }
18-
>conflictingReturn : (b: 3) => false
18+
>conflictingReturn : (b: 3) => true
1919
>b : 3
2020
>false : false
2121

@@ -26,7 +26,7 @@ export function conflictingReturn(b) { return false }
2626
* @return {false}
2727
*/
2828
export function conflictingBoth(d) { return false }
29-
>conflictingBoth : (d: 5) => false
29+
>conflictingBoth : (c: 4) => true
3030
>d : 5
3131
>false : false
3232

testdata/baselines/reference/submodule/compiler/argumentsObjectCreatesRestForJs.errors.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
main.js(3,9): error TS2554: Expected 0 arguments, but got 3.
2-
main.js(5,1): error TS2554: Expected 2 arguments, but got 0.
3-
main.js(6,16): error TS2554: Expected 2 arguments, but got 3.
2+
main.js(6,16): error TS2554: Expected 0-2 arguments, but got 3.
43

54

6-
==== main.js (3 errors) ====
5+
==== main.js (2 errors) ====
76
function allRest() { arguments; }
87
allRest();
98
allRest(1, 2, 3);
109
~~~~~~~
1110
!!! error TS2554: Expected 0 arguments, but got 3.
1211
function someRest(x, y) { arguments; }
1312
someRest(); // x and y are still optional because they are in a JS file
14-
~~~~~~~~
15-
!!! error TS2554: Expected 2 arguments, but got 0.
16-
!!! related TS6210 main.js:4:19: An argument for 'x' was not provided.
1713
someRest(1, 2, 3);
1814
~
19-
!!! error TS2554: Expected 2 arguments, but got 3.
15+
!!! error TS2554: Expected 0-2 arguments, but got 3.
2016

2117
/**
2218
* @param {number} x - a thing

testdata/baselines/reference/submodule/compiler/argumentsPropertyNameInJsMode1.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
a.js(9,7): error TS2554: Expected 1 arguments, but got 3.
1+
a.js(9,7): error TS2554: Expected 0-1 arguments, but got 3.
22

33

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
a.js(5,6): error TS2554: Expected 1 arguments, but got 3.
1+
a.js(5,6): error TS2554: Expected 0-1 arguments, but got 3.
22

33

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

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

testdata/baselines/reference/submodule/compiler/argumentsReferenceInFunction1_Js.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
index.js(1,25): error TS7006: Parameter 'f' implicitly has an 'any' type.
2-
index.js(13,29): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f: any]'.
2+
index.js(13,29): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[f?: any]'.
33

44

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

testdata/baselines/reference/submodule/compiler/jsFileFunctionParametersAsOptional.errors.txt

Lines changed: 0 additions & 24 deletions
This file was deleted.

testdata/baselines/reference/submodule/compiler/jsFileFunctionParametersAsOptional2.errors.txt

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)