steep icon indicating copy to clipboard operation
steep copied to clipboard

Proposal: Add method annotations: primitive:nil? and primitive:not_nil?

Open tk0miya opened this issue 2 years ago • 3 comments

To represent methods like Object#blank? and Object#present? in ActiveSupport, this adds method annotations primitive:nil? and primitive:not_nil?.

They will be considered as same as nil? and not nil? internally.

refs: #472

Please let me know your opinion about implementation, the naming of annotations, and so on.

tk0miya avatar Sep 01 '23 17:09 tk0miya

Someone in Ruby Discord asked if we can write “truthy”, i.e. exact opposite of false | nil. Would that in the RBS core be more preferred?

ParadoxV5 avatar Oct 29 '23 03:10 ParadoxV5

The goal of this PR is to provide type narrowing to Steep. So this is not related to the "truthy" type that you mentioned.

For example, the following code is available in Ruby on Rails:

name = params[:name]  #=> String?
if name.present?
  name  #=> String
end

But current steep does not support this type narrowing.

This PR adds a new feature to define type narrowing methods via primitive:nil? and `primitive:not_nil? annotation.

tk0miya avatar Oct 29 '23 11:10 tk0miya

If we defined #present? as:

class Object
  %a{pure} def present?: () -> bool
end

class NilClass
  %a{pure} def present?: () -> ::FalseClass
end

In the example below, shouldn't Steep have enough information to narrow name from String? to String inside the conditional?

name = params[:name]  #=> String?
if name.present?
  name  #=> String
end

This doesn't appear to work currently, but it seems like it should.

derikson avatar Mar 04 '24 18:03 derikson