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:
a = [1, nil].sample # a is `Integer | nil`
unless a.nil?
# a is `Integer` here
p a + 1
end
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's present?.
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
class Object[T?]
def nil?: () -> self is nil
end
class Object[T?]
def present?: () -> self is T
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
Objectlike 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