Skip to content

Proposal: @rbs return: infer! and #: infer! #152

@KieranP

Description

@KieranP

I'm building an app on mruby and wanted to add Array#index_by.

Ruby:

class Array < Object
  def index_by
    result = {}
    each { |elem| result[yield(elem)] = elem }
    result
  end
end

RBS:

class Array[unchecked out Elem] < Object
  def index_by: () { (Elem) -> (String | Symbol) } -> Hash[String | Symbol, Elem]
end

Then utilizing it like so:

class Items
  TYPES = [
    Shield,
    Sword
  ].index_by do |v|
    v.name.to_s.demodulize
  end
end

Now, BEFORE the rbs files are generated, the VSCode steep extension is correctly inferring the type as:

::Hash[(::String | ::Symbol), (singleton(::Items::Shield) | singleton(::Items::Sword))]

But when I run the rbs-inline generator, the RBS file gets TYPES: untyped because I don't have a RBS comment, and then VSCode reports it as untyped, and shows errors.

Now, I could add #: ::Hash[(::String | ::Symbol), (singleton(::Items::Shield) | singleton(::Items::Sword))], but it seems redundant, because each time I add a value to the array, I now need to add it to the RBS also.

Consider also this:

class Item
  NAME = 'Kieran'.freeze

  def format_name
    NAME.split('').join
  end
end

rbs-inline currently outputs this:

class Item
  NAME: untyped

  def format_name: () -> untyped
end

But steep auto infers these just fine. rbs-inline should use this when generating rbs files for variables/methods withou return types.

class Item
  NAME: ::String

  def format_name: () -> ::String
end

I'd like to propose that rbs-inline use steeps correct auto-detected type when generating RBS files for values it can infer the type from. It could do this automatically or if you want it to be defined, I propose a @rbs return: infer! and #: infer!

class Item
  NAME = 'Kieran'.freeze #: infer!

  # @rbs return: infer!
  def format_name
    NAME.split('').join
  end
end

If you use infer! and it's not actually able to be inferred, it should throw an error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions