Why do some types’ types end with .Type when typed in the REPL but some don’t?

For instance:

 20> String.self
$R16: String.Type = String
 21> KeyPath<Any, Any>.self
$R17: KeyPath<Any, Any>.Type = KeyPath<Any, Any>.Type
 22> type(of: {(it: Int) in type(of: it)}) 
$R18: ((Int) -> Int.Type).Type = (Int) -> Int.Type

Why is String not suffixed with .Type on the right?
Why is the final .Type discarded in the last one also?

I don’t know the answer, but I think the outlier is the middle line ($R17). Both the first and last lines of output ($R16 and $R18) have the same pattern, namely “SomeType.Type = SomeType”.

It is only the middle line that appends an additional “.Type” to the end of the right-hand side, and that is also the only example with a generic type.

To gain more data, I would suggest trying some more inputs, including the use of subclass types as their superclass type, both with and without generic parameters on each type.

1 Like

When you type a "normal" expression into the REPL, the output looks like this:

$ swift repl
  1> 5 + 3
$R0: Int = 8

So the output format of the REPL is something like this:

  1> [some expression]
$R0: [type of expression] = [result of expression]

In your example:

 20> String.self
$R16: String.Type = String

The type of the expression String.self is String.Type and the value/result of the expression is String aka String.self. T and T.self refer to the same thing: the type T itself. Whereas T.self refers to the metatype (the type of the type T).

This doesn't explain the outlier @Nevin mentioned, of course. I can't explain that one, either.

1 Like

Interestingly, print(KeyPath<Any, Any>.self) does not have a .Type suffix.