Can typeof() return an alias?

Is it possible to have a type alias where typeof() returns the alias rather than the base type
e.g.

XString    = String
x::XString = "ab"
typeof(x)      # gives  XString    not String

Use Case The below code produces a string from the ::String elements of a struct.


using NamedTupleTools, Dictionaries, Chain, Lazy, Parameters

◀join(a,b)   = join(b,a)
◀filter(a,b) = filter(b,a)
◀map(a,b)    = map(b,a)


@with_kw struct X
    a::String
    b::String
    c::Int
end

XtoString(x::X) = @chain x begin
    ntfromstruct
    Dictionary
    ◀filter(x->typeof(x)==String)
    pairs
    ◀map(( (k,v),) -> "$k=$v" )
    join(',')
end

@> X( a= "blue", b="green", c = 1)     XtoString   #"a=blue,b=green"

I’d like to instead filter on typof(x)==XString. e.g.

@with_kw struct X2
    a::XString
    b::XString
    c::String
end

@> X( a= "blue", b="green", c ="red")     X2toString   #"a=blue,b=green"

If there’s a better way to build this function would be interested as well.

no

XString    = String

this is just the same type, it’s like a=3 and you can’t see “a” no matter what you do when variable a is passed to a function.

The minimal way to custom display is to make a new type

struct XString
    data::String
end

unfortunately that makes it a structure not a String. So i can’t do

x = XString("abc")
x * "def"

to get the string, you’d always have to write x.data

well you have to teach it how to *

XString is just an alias of String, i.e., it denotes the same type for all practical purposes. In particular,

julia> XString = String
String

julia> XString == String
true

and accordingly you can simply replace String with XString in your filter condition:

julia> filter(x -> typeof(x) == String, [1, "a", 2, "bc"])
2-element Vector{Any}:
 "a"
 "bc"

julia> filter(x -> typeof(x) == XString, [1, "a", 2, "bc"])
2-element Vector{Any}:
 "a"
 "bc"

I.e., it does not matter that typeof(x) will return (and print) String as its just the same an XString per the assignment XString = String. If there is no need to ever reassign the type alias, I would probably use const XString = String which makes it even more clear that XString is just an alternative name for String.
Note that this also means that your code will work with regular strings as there is no way to ever distinguish them from XStrings. If it is required that they are separate types, you will need to create a new type as suggested by @jling and define all methods required on that type, e.g., by forwarding to the underlying data field:

struct MyXString
    data::String
end

Base.:*(u::MyXString, v::MyXString) = MyXString(u.data * v.data)
1 Like