The closest thing that typing has to type variables is typing.TypeVar. Their use is to create a generic class, in the same way that you write list[int] or Mapping[str, str].
So we can rewrite your code so that BaseCls is a generic type, with a type variable ReturnsType. (You should only use all caps for constants.)
The subclasses IntCls and StrCls "assign" to the type variable by including the type inside square braces after the type they are subclassing.
from typing import TypeVar, Generic, Any ReturnsType = TypeVar('ReturnsType') class BaseCls(Generic[ReturnsType]): def cast_to_return_type(self, value: Any) -> ReturnsType: return some_work_that_returns_self_RETURNS_TYPE() class IntCls(BaseCls[int]): pass class StrCls(BaseCls[str]): pass