Skip to main content

4 posts tagged with "release"

View All Tags

Type Inference: Write Less, Type More

T-Ruby now automatically infers return types from your code. No more explicit annotations for obvious types!

What's New​

Previously, you had to write:

def greet(name: String): String
"Hello, #{name}!"
end

Now, the return type is optional:

def greet(name: String)
"Hello, #{name}!"
end

T-Ruby infers that greet returns String and generates the correct RBS:

def greet: (name: String) -> String

How It Works​

The new type inference engine analyzes method bodies to determine return types:

  • Literal inference: "hello" → String, 42 → Integer
  • Method call tracking: str.upcase → String
  • Implicit returns: Ruby's last expression becomes the return type
  • Conditional handling: Union types from if/else branches

Examples​

Simple Methods​

class Calculator
def double(n: Integer)
n * 2
end

def is_positive?(n: Integer)
n > 0
end
end

Generated RBS:

class Calculator
def double: (n: Integer) -> Integer
def is_positive?: (n: Integer) -> bool
end

Instance Variables​

class User
def initialize(name: String)
@name = name
end

def greeting
"Hello, #{@name}!"
end
end

Generated RBS:

class User
@name: String

def initialize: (name: String) -> void
def greeting: () -> String
end

Technical Details​

The inference system is inspired by TypeScript's approach:

  • BodyParser: Parses T-Ruby method bodies into IR nodes
  • TypeEnv: Manages scope chains for variable type tracking
  • ASTTypeInferrer: Traverses IR with lazy evaluation and caching

For a deep dive into the implementation, check out our technical blog post.

Try It Now​

Update to the latest T-Ruby and enjoy automatic type inference:

gem update t-ruby

Your existing code will work as before - explicit types still take precedence. The inference only kicks in when return types are omitted.

Feedback​

We'd love to hear your experience with type inference. Found an edge case? Have suggestions? Open an issue on GitHub.

Happy typing!