Здесь есть пара решений.
- Инициализируйте переменную экземпляра вне метода и присвойте ей аннотацию типа:
# typed: strict
# frozen_string_literal: true
module Util
extend T::Sig
@git_sha = T.let(nil, T.nilable(String))
sig { returns(String) }
def self.git_sha
@git_sha ||= ENV.fetch(
'GIT_REV',
`git rev-parse --verify HEAD 2>&1`
).chomp
end
end
→ Посмотреть на sorbet.run
Это предпочтительное решение. Концептуально, у этого класса есть две фазы выполнения: когда он инициализируется и когда он используется. Если переменной экземпляра не дана аннотация типа, когда она инициализируется в Sorbet, она будет везде T.untyped
(или ошибка в # typed: strict
). Потому что, если он не аннотирован при инициализации, Сорбет не может знать, какой путь к коду может сначала записаться в это местоположение. (Даже в этом случае, когда есть одно местоположение, Сорбет не проводит такого глобального анализа.)
- Используйте другой уровень строгости .
Документы по уровням строгости .
Если вы считаете слишком обременительным добавление аннотации типа, вы можете отказаться от аннотации типа, используя # typed: true
, где ошибка, требующая аннотации типа для переменных экземпляра, отключается.