如何将来自 gem 的类型包含在签名中?

How do I include types from a gem with sigs?

假设我有一个名为 thing 的共享 gem,它被用于多个其他项目,例如 example-project。我想在 thing gem 中使用 sorbet 来利用类型检查。如何让我的消费项目检查我 gem 中的类型?

例如,代码可能如下所示

东西gem

# typed: strict

require 'sorbet-runtime'

class Thing
  extend T::Sig

  sig { params(phrase: String).returns(String) }
  def say(phrase)
    "Thing said: '#{phrase}'"
  end
end

示例项目

# typed: strict

require 'thing'

Thing.new.say(1) # Should cause a type error

会发生什么

在运行srb rbi update之后,我得到一个sorbet/rbi/gems/thing.rbi

class Thing
  def say(*args, &blk); end
  extend T::Private::Methods::MethodHooks
  extend T::Private::Methods::SingletonMethodHooks
  extend T::Sig
end

这没有我预期的来自 gem 的信号,并且 srb tc 没有引发我预期的错误。

我尝试过的其他东西

在gem

中包含rbi/thing.rbi

这行得通,但我宁愿在 gem 代码中内联编写我的签名,也不愿维护单独的 rbi 文件。是否有任何工具可以将 .rb 文件与 sigs 一起输出并输出 .rbi 文件(并且可能从 .rb 文件中删除 sigs 以便它们 gem 可以在没有的情况下分发冰糕)。我正在考虑类似于打字稿 tsc --declaration 的工作流程,它来自 .ts => .d.ts + .js.

https://github.com/AaronC81/brain_freeze 是一个新项目,旨在使从具有内联声明的 RB 文件生成 RBI 文件成为可能。现在还早,但可能值得一试