Brainstorming, not advocating:

Thinking about #60561 about how to make Index[timestamp[pyarrow]] either be a DatetimeIndex or behave like one, one approach is to take DTI methods and move their logic to the base class behind a self.dtype.kind == "M" check. This almost works, but some of those methods check for self.freq which the base class doesn't have.

But freq for DTI/TDI means basically the same thing as step does for RangeIndex. And step could be well-defined for any dtype where subtraction is defined.

What if we defined step on the base class, had it be an alias for freq on DTI/TDI? Could get rid of a ton of special-casing in the DTI/TDI classes. When it is present, it would enable some optimizations (e.g. we know we are monotonic, can fastpath some setops).

Downside: it would have a different type for numeric and datetime/timedelta indexes

xref #46484 about extending RangeIndex to support floats, #47227 about fixing the overloading of the word "freq".