Рекурсивные типы в сорбете

#ruby #sorbet

Вопрос:

Как можно объявить псевдоним типа, который может содержать ссылку на себя? Например, чтобы отметить функцию, возвращающую структуру, подобную JSON.

Пытаясь:

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

Выдает следующую ошибку:

Псевдоним типа Foo участвует в цикле

Ответ №1:

Начиная с версии 0.5.x это невозможно, так как псевдонимы типов не поддерживают циклы.

Один из вариантов-снизить типизированность вашего результата и просто сделать его:

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

Если вы действительно хотите проверить тип, вы можете выразить что-то подобное, обернув результат в a T::Struct . Однако объекты больше не будут такими плоскими, как изначально (см. в <a rel=»noreferrer noopener nofollow» href=»https://sorbet.run/## typed: true

class Foo 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