冰糕中的递归 type_alias

Recursive type_alias in sorbet

如何声明一个可以包含对自身的引用的类型别名?例如标记一个函数返回一个 JSON-like 结构。

正在尝试:

Foo = T.type_alias { T.any(Integer, T::Array[Foo]) }

出现以下错误:

Type alias Foo is involved in a cycle

从版本 0 开始。5.x,这是不可能的,因为类型别名不支持循环。

一种选择是降低结果的类型化程度,并使其成为:

Foo = T.type_alias { T.any(Integer, T::Array[T.untyped]) }

如果你真的想要类型检查,你可以通过将结果包装在 T::Struct 中来表达这样的东西。不过,对象将不再像原来那样平坦(参见 sorbet.run):

class Foo < T::Struct
  prop :content, T.any(Integer, T::Array[Foo])
end

myFoo = Foo.new(content: 1)
content = myFoo.content
case content
when Integer
  puts "It was an integer!"
  T.reveal_type(content)
when Array
  puts "It was a Foo!"
  T.reveal_type(content)
else
  T.absurd(content)
end

编辑 (2022-02):关于 type_alias has been updated to address recursive definitions. It includes an example for JSON-like structures in sorbet.run 的文档。