Add staticType(of:)

Recently I copied some code into an online compiler and I was wondering which type was inferred at some point. I've used type(of:) before, but in this case I actually wanted to know the static type. I asked on the forum and there doesn't seem to be a standard way to get the static type. Eventually, we came up with this:

func staticType<T>(of _: T) -> T.Type {
    return T.self
}

So, this makes the following possible:

let a = someFunction()
print(staticType(of: a))

In an IDE it might not make much sense, but it could be useful when using an online compiler, or just hacking some script with a basic editor. Or perhaps there is some other use case where you'd want to obtain the static type, besides just for printing it?

I'm not sure how much it will be used, I didn't really need it until recently, but I think it also makes sense to add it for completeness.

Would this be a good addition to the standard library? And can anyone come up with a different use case than just printing the type?

1 Like

+1
It would be nice to have when teaching other people what is a static and dynamic type.
It would also make it clearer that type(of:) returns dynamic type, if you can see in autocompletion that there's a different function for a static one.
and sometimes Xcode has a bad day and I don't trust anything that comes out of it.

let foo = getFoo() // variable with a type that is very long, or you're not sure how it's spelled
staticType(of: foo).staticMethod()

It's not really a very good use case, though.

I support this, i don’t see any end use for it in an application, but it’s a helpful debugging tool and there is no alternative way of getting this information (on Linux, or on OSX without XCode) short of deliberately breaking the code and hoping the compiler leaks the inferred type in the error message

For the simple case where you just want to see the type of something, doesn't String(reflecting: x) do that?

If you want to find the type and use static methods / variables, wouldn't that be better as part of the reflection overhaul?

No.

protocol P {}

struct A:P {}

let a:P = A()

func printStaticType<T>(of _:T) 
{
    print(T.self)
}

print(type(of: a))
print("\(reflecting: a)")
printStaticType(of: a)
A
A()
P

1 Like

Interesting. I've wanted an Xcode shortcut to show inferred types for a while, but this seems like an interesting run time implementation.

Keep in mind that this function will generate a lot of confusion if you use it with protocols. Metatypes extracted from protocols in a generic context won‘t be P.Type, but P.Protocol since static P.Protocol is not a subtype of dynamic P.Type but only of dynamic Any.Type (protocols do not conform to themselfs). For types like structs etc. static T.Type : dynamic T.Type relationship is valid.

Therefore this will generate some headaches:

print(type(of: staticType(of: (AStruct() as Proto)))) // Proto.Protocol

For more information please read this.

1 Like

I've read SE-0126, but I probably need to read it again to fully (mostly) comprehend it.

However, it looks like SE-0126 will change a lot. Would it be better to make staticType(of:) part of SE-0126, or perhaps pitch it again after SE-0126 has been accepted?