Contextually type IIFE params by their arguments#8483
Conversation
|
|
||
| function isIife(func: FunctionExpression | MethodDeclaration) { | ||
| return (func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction) && | ||
| func.parent.kind === SyntaxKind.ParenthesizedExpression && |
There was a problem hiding this comment.
not necessarily. this is a valid iife (function f() {)} ()).
There was a problem hiding this comment.
I suggest using the skipParenthesizedNodes function before checking for a call expression at the top.
There was a problem hiding this comment.
Done, although skipParenthesizedNodes actually goes down, not up (expression = expression.expression), so I just wrote an inline loop to go up (parent = parent.parent)
And address bug with contextually typed arguments that the PR changes exposed.
|
@ahejlsberg once I fixed the parenthesis walker, I had trouble with contextually typed lambdas, eg The compile passes and fails correctly, but the .types files stringifies |
| const indexOfParameter = indexOf(func.parameters, parameter); | ||
| if (iife.arguments && indexOfParameter < iife.arguments.length) { | ||
| if (parameter.dotDotDotToken) { | ||
| return createArrayType(getUnionType(map(iife.arguments.slice(indexOfParameter), getTypeOfExpression))); |
There was a problem hiding this comment.
do you really need the array allocation here.
There was a problem hiding this comment.
Switched to a for loop. As we discussed in person, it would be nice to have a map over a range for general use.
Also allocate once instead of twice.
|
Lgtm |
Fixes #4142.
Right now rest parameters look at the first matching argument to get their contextual type. This might be wrong.