You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用中Sorbet类型别名应声明在何处?

Sorbet类型别名在Rails中的正确声明位置

问题原因

你在sorbet/rbi/shims/timestamp.rbi中定义的类型别名仅对Sorbet静态检查(srb tc)生效——因为shims/目录下的RBI文件是Sorbet专属的静态类型补充文件,Ruby运行时不会加载这些文件,所以RSpec执行时会抛出uninitialized constant错误。

解决方案

根据类型别名的使用范围,选择以下两种方式:

1. 全局可用的类型别名

如果需要在整个应用中使用Timestamp,在app/目录下创建一个专门存放类型定义的Ruby文件(Rails会自动加载app/下的文件):

# app/types/timestamp.rb
# 同时定义运行时常量和Sorbet类型别名
Timestamp = T.type_alias { T.any(Time, ActiveSupport::TimeWithZone) }

这样既满足Sorbet静态检查的需求,又能让Ruby运行时识别到Timestamp常量。

2. 仅在特定类/模块内使用的类型别名

如果Timestamp只在ShowamiService中使用,直接在服务类的源码里声明类型别名:

# app/services/showami_service.rb
class ShowamiService
  # 在类内部定义类型别名
  Timestamp = T.type_alias { T.any(Time, ActiveSupport::TimeWithZone) }

  sig { params(availabilities: T::Array[OrderAvailability], now: Timestamp).returns(T.nilable(Timestamp)) }
  def calculate_local_start_at_from(availabilities, now)
    # 业务逻辑实现
  end
end

这种方式避免了全局常量污染,同时确保静态检查和运行时都能正常识别。

补充说明

  • Sorbet的RBI文件分为多种类型:shims/用于补全第三方库的静态类型,运行时不加载;而自定义的应用代码RBI文件(如sorbet/rbi/app/下的)若要运行时生效,需要额外配置,但直接在Ruby源码中定义类型别名是最可靠的方式,兼顾静态检查和运行时需求。

内容的提问来源于stack exchange,提问作者François Beausoleil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:10:54