-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type inference fails to recognize never when it's the result of a template tag function #61039
Comments
Only analyzing call statement is an intentional trade-off to achieve reasonable performance (since making new control flow nodes incurs expense on all analysis); you'd see the same thing if you had written e.g. function typeCheckerIncorrectlyDoesNotLikeThis(arg?: string): string {
if (arg) {
return arg;
}
const p = failTemplate`bad`;
} In situations like this, you can write return failTemplate`bad`; which will be analyzed as requested |
I would argue that a template invocation is a call statement (which it is in terms of everything but syntax), so I don't see any fundamental semantic difference between the case that's handled correctly and the case that's handled wrong in terms of the control flow analyses they imply. If I write the code in the form that is handled correctly I'm paying the performance cost of that analysis, and that case is much more common so the performance savings of skipping it in the other case seems like a de minimis gain. Especially considering that this is a build-time performance cost. The whole point of using a tool like TypeScript is to spend cycles at build time to avoid having to spend cycles at run time. More to the point, the very reason many of us use TypeScript is because we are concerned about correctness. Choosing to sacrifice correctness for (build-time!) performance seems absolutely bizarre to me. I can make anything at all infinitely fast if I don't care if it's correct. Also, and though I'll grant that this is not dispositive, the |
Fair points. Can I ask why you chose to use a template tag here instead of a function call? |
Certainly! The use case is for constructing
where the condition being However, you can instead use a pattern like this:
where the tagged template You could, of course, just write:
but notationally this is much more verbose and clunky, which detracts considerably from readability if you have a lot of them and also discourages developers from using these kinds of checks as liberally as we'd like. A plausible fallback might indeed be to replace the tagged template with a function call:
Arguably this raises the question why one should have to insert a couple of nugatory parentheses just to have the flow of control analyzed right, but that's academic because TS doesn't correctly analyze this case either. |
π Search Terms
tagged template literal never type
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABMAhjANgFQKYFsAO6KU2AFAM5QBOMYA5uQFyI4FEkDK1tDAglVRQBPADSIAdJIBuKdCGxNEKMEIDaAXQCUzMNinYqiAN4AoROcRQAFlTgB3RLocBRAXCqkA5KgytCxbCV0O2FySxt7ck9NAG4TAF8TE1BIWARkNHQAMXBoeDBSbUc9A2MzC2tbBydEV1sPb0yc1PygkKEwysjouMSTAHp+xABhdypsaHQhRHGIODowGAAvBXDAlLz0iFl0RAATOFWwOCgZ7CgQKjBk3LSkKCF8bGGrCYBrA1GBCagpgBkYB9yJgrDByKQUFQ6AB+ZiUGj0IrwnhlCyIGDARAQqGaVFoizjC5XJRQuJoxJonzZW75Qq9JKDRAASUgYx+U2QRAYazORPuj0Cdhg1mYzU2SCIEDeYWwYD2KMJlyQlACuFlp2Ue15SssAv2hzCx1OtAgcj2gU84HNwFo2D2nnEpAATABmABsbs0Nxa6QeTxe7wMLLm30mQgAIgaAHInAEfEFg7EwuHcREphF0PHmDFYyF0XGmfEE846vNkiwUixUvzsbAAAwARig9nX6QMhl9Zr9puRsKtrMQeb25nLtcSVSQ1WBjWFwOMUBArCgG+hsN7xbr-a8pZ82WHIwoY1A49gE+C87DEMi01fU5nCxYc0mC+Ui4riWXX4hK+YqWK7nSX7vkgnivOg6BwJ4baMlkmSdHAV59uEg7WIEw4IFqwG3qq6rorOYDzouy6ruudybs824fFQwZ7t2J7AqC55Qpe175umKIPtmmLPlm+JYZ+5JftWeD+CQjbNq2QElsSoHYOBkH0kAA
π» Code
π Actual behavior
The invocation of a template tag function (via a tagged template literal) that is declared to return type
never
terminates the flow of control of the containing function, but the type checker does not recognize this and complains as if execution had continued beyond the invocation.It appears, to my naive sensibilities, that the use of a tagged template literal is not recognized as a function invocation even though it is one. However, if the return type of the tag function is, say,
number
, the type inference engine does correctly recognize this, so it seems like the issue is specifically with the flow control logic associated withnever
.π Expected behavior
A template literal using a
never
returning template tag function should be recognized the same as an ordinary invocation of anever
returning function.Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: