-
Notifications
You must be signed in to change notification settings - Fork 216
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
Support type narrowing #1822
Comments
🆙 for something (not necessarily this) From soutaro/steep#905 (comment), the current solution is class Object
def nil?: () -> bool # cannot be assertively `false` or else `NilClass#nil?` breaks polymorphism of `NilClass < Object`
end
class NilClass
def nil?: () -> true
end Or, with #1639 (reply in thread), class Object
def nil?: [self < nil] () -> true
| () -> bool
end But in either case, the prickly part is that there’s no format to tell that non- class Object
def nil?: [self < nil] () -> true
| [self !< nil] () -> false # ⬅ a way to declare a negative constraint
end Alternatively, if the overload semantics changes so that earlier branches subtractively narrow latter branches, class Object
def nil?: [self < nil] () -> true
| () -> false # `else`
end |
|
Ref: soutaro/steep#472
Currently RBS doesn't have any syntax to narrow types in control flow.
So there's no way to achieve the following:
But actually, both Sorbet and Steep treat some special methods to narrow types
https://github.com/sorbet/sorbet/blob/718bc64f895abeeff88f56efbc92a3554ffaa4f2/infer/environment.cc#L536-L545
https://github.com/soutaro/steep/blob/a868762c2bd09f0954b05cdd9eab1819e14a51d3/lib/steep/interface/builder.rb#L709-L721
Ideally, I think we need to have a syntax considering Ruby gems which extend
Object
like ActiveSupport'spresent?
.I'm not very familiar with type system though, I guess the syntax would be similar with TypeScript's type predicates
https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
The text was updated successfully, but these errors were encountered: