Improve control flow analysis of type assertions#26679
Conversation
| * to cache the result. | ||
| */ | ||
| function getTypeOfExpression(node: Expression, cache?: boolean) { | ||
| const expr = skipParentheses(node); |
There was a problem hiding this comment.
I don't think we can do this quite like this in this codepath - this means this fast path will cause us to skip jsdoc type assertions in JS, which look like /* @type {Type} */(expression).
There was a problem hiding this comment.
Same example as repro, but in JS:
// @ts-check
/**
* @typedef {{message: {id: string}}} DataShape
*/
/**
* @param {string | number} id
* @return {any}
*/
function getObject(id) {
return {} as any
}
;(() => {
/* @type {string | number} */
let id = 'a'
while (1) {
const data = /* @type {DataShape} */(getObject(id))
const message = data.message
id = message.id
}
})()There was a problem hiding this comment.
We can do it this way, it just means that we won't bail out early during control flow analysis. It's simply a matter of how many cases we feel are worthwhile handling in getTypeOfExpression. In a TypeScript file it matters because you'll get an error with --noImplicitAny. In a JavaScript file it just means another any, which are a dime a dozen already, so to speak. So, I think it is fine.
There was a problem hiding this comment.
noImplicitAny still works in JS files with checkJs, so the bug does still exist in JS then, it just has a smaller audience.
Fixes #26655.