Correct use of promotion and conversion

I defined the following:

import Base: promote_rule

struct RationalNumber{T<:Integer} <: Real

#RationalNumber{T}(x::S) where {T<:Integer, S<:Integer} = RationalNumber(x, 1) 

RationalNumber(n::T, d::T) where {T<:Integer} = RationalNumber{T}(n,d) 
RationalNumber(n::Integer, d::Integer) = RationalNumber(promote(n,d)...)
RationalNumber(n::Integer) = RationalNumber(n, one(n))
RationalNumber{T}(n::Integer) where {T<:Integer} = convert(T, n) |> RationalNumber

promote_rule(::Type{RationalNumber{T}}, ::Type{S}) where {T,S<:Integer} = RationalNumber{promote_type(T, S)}
promote_rule(::Type{RationalNumber{T}}, ::Type{RationalNumber{S}}) where {T,S<:Integer} = RationalNumber{promote_type(T, S)}

function, r::RationalNumber)
    print(io, "$(r.num)//$(r.den)")

I am working on getting comparison to behave properly. Currently, it’s fine when I compare a RationalNumber{T} to another with the same T:

julia> RationalNumber{Int8}(2,3) == RationalNumber{Int8}(2,3)

But I get an error when comparing a RationalNumber{T} and RationalNumber{U} where T != U:

julia> RationalNumber(2,3) == RationalNumber{Int8}(2,3)
ERROR: MethodError: no method matching RationalNumber{Int64}(::RationalNumber{Int8})

Closest candidates are:
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  (::Type{RationalNumber{T}} where T<:Integer)(::Any, ::Any)
   @ Main Untitled-1:848
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50

 [1] convert(#unused#::Type{RationalNumber{Int64}}, x::RationalNumber{Int8})
   @ Base ./number.jl:7
 [2] _promote
   @ ./promotion.jl:358 [inlined]
 [3] promote
   @ ./promotion.jl:381 [inlined]
 [4] ==(x::RationalNumber{Int64}, y::RationalNumber{Int8})
   @ Base ./promotion.jl:449
 [5] top-level scope
   @ REPL[4]:1

I expected my second promote_rule method to handle this, but I guess I’m misunderstanding something. Can someone help me properly fix this? I’m inclined to write another constructor which handles the MethodError, but I’m not sure if this is the best way to do it.

You’re just missing a constructor that makes a RationalNumber from another of a different type:

RationalNumber{T}(r::RationalNumber) where {T} = RationalNumber{T}(r.num, r.den)