-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Rule proposal: ensure type predicate assignable to narrowed parameter #9768
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
Comments
I think this is us taking over the type checker's job and I don't think we've ever had similar logic before (probing something's type where there's no expression in code). Do you have a poc that it's doable in the form of a custom rule? |
Not yet... which is also partially why I hadn't proposed this previously. But, my (optimistic) thinking is that it would be subject to the same or similar detection as detecting |
I don't think that this is actually possible to do. Without that power we can't inspect the type in a certain control flow location. That aside - we'd have to walk TS's control flow graph somehow to "get" the spot immediately before the termination of the branch -- probably doable -- haven't seen TS's control flow APIs though. Checking if the refined type is exactly (or assignable to) the predicate type is doable now that we have the relationship API. Though there are a few places that I know I'd immediately disable the rule. |
So, ah, out of scope for us? Close with another rueful wontfix? 😞 |
Hmm, I get that there may be slightly more control flow analysis to consider, but I'm not quite following why the refinement analysis isn't the same level of difficulty as in #9764. Am I missing something obvious? If so, totally fine to close! |
#9764 has a very slim, controlled scope:
All that rule needs to do is validate that the function adheres to those things and if it does, report. OTOH This issue is about trying to figure out what the type of the refined parameter is at a given I do love the idea of the rule but yeah I just don't think it's possible for us to build. |
I feel like we should document some common limitations of typed rules:
|
Right, but, still, how do you plan to solve that for #9764, then? Like, how would you actually determine that this is an inferrable type predicate? declare function myTypeGuard(x: unknown): x is string | number;
function maybeInferredTypePredicate(x: unknown) {
return myTypeGuard(x);
} (to say nothing of this, which, believe it or not, is inferred as a type predicate) function maybeInferredTypePredicate(x: unknown) {
const xIsStringOrNumber = myTypeGuard(x);
return xIsStringOrNumber;
} |
That rule doesn't specifically care about correctness - it just cares about the rules for inferring the predicate.
That last dot point is going to be the complicated bit to solve for sure and I doubt we'll be able to handle all the cases. We'll need to build logic that flags things that look like refinements. In your examples it's easy cos it's a call to an existing predicate which is an obvious refinement. Again the important distinction is that #9764 won't need to determine the actual types of things - just that it has to walk backwards from the return statement and go "does it look like a refinement of the parameter?" |
Gotcha. Well, I shall wontfix it for now.👍 Thanks for talking through this! |
Before You File a Proposal Please Confirm You Have Done The Following...
My proposal is suitable for this project
Description
TS enforces that a type in a type predicate be assignable to the type of the associated parameter.
That is to say
is illegal, since
null
cannot be assigned tonumber
. That's a good and sensible check!Within the function's implementation, though, the parameter's type may become narrowed. I propose we create a rule to report if the function returns
true
when the predicate type is not assignable to the narrowed type, since that is likely to be an error.Fail Cases
Pass Cases
Additional Info
This relates to @bradzacher's proposal in Rule proposal: prevent an explicit
: boolean
return type annotation if a predicate return type could be inferred #9764 (and I shamelessly stole his example code from that issue 🙂). Note that this might be tricky to implement, but I think that if Rule proposal: prevent an explicit: boolean
return type annotation if a predicate return type could be inferred #9764 is doable, then this would be too.While this proposal talks about prohibiting returning
true
when it doesn't make sense, it might also make sense to have an analogous check for thereturn false
case.... Haven't thought deeply about that part yet.The text was updated successfully, but these errors were encountered: