PrepareFor
PrepareFor

Reputation: 2598

what is T.Type in swift

Can anyone tell me what is T.Type when I use JSONDecoder().decode()?

I think it is type to decode data what I encoded.

So many example use above method like this:

JSONEncoder().decode([People].self, from: data)

If I check that method's definition I can see T.Type.

I know the generics but what is T.Type?

What's the difference between just T and T.Type?

when we declare some variables, we allocated their types like this

var someValue: Int , not var someValue: Int.self

What is the T.Type exactly and Type.self?

Upvotes: 16

Views: 14385

Answers (1)

Daniel Hall
Daniel Hall

Reputation: 13679

  • T.Type is used in parameters and constraints to mean "the type of the thing itself, not an instance of the thing".

    For example:

    class Example {
        static var staticVar: String { return "Foo" }
        var instanceVar: String { return "Bar" }
    }
    
    func printVar(from example: Example) {
        print(example.instanceVar)  // "Bar"
        print(example.staticVar) // Doesn't compile, _Instances_ of Example don't have the property "staticVar"
    }
    
    func printVar(from example: Example.Type) {
        print(example.instanceVar)  // Doesn't compile, the _Type_ Example doesn't have the property "instanceVar"
        print(example.staticVar) // prints "Foo"
    }
    
  • You get a reference to a Type's .Type (the Type object itself) at runtime by calling TheType.self. The syntax TheType.Type is used in type declarations and type signatures only to indicate to the compiler the instance vs. type distinction. You can't actually get a reference to, for example, Int's type at runtime or in your function implementations by calling Int.Type. You would call Int.self

  • In the example code var someValue: Int, the specific notation identifier: Type (in this case, someValue: Int) means that someValue will be an instance of Int. If you wanted someValue to be a reference to the actual type Int, you would write var someValue: Int.Type = Int.self Remember that the .Type notation is only used when declaring types and type signatures to the compiler, and the .self property is used in actual code to retrieve a reference to the type object itself at execution time.

  • The reason why JSONDecoder().decode requires a parameter of T.Type (where T conforms to Decodable) is because any type conforming to Decodable has an initializer init(from decoder: Decoder). The decode method will need to call this init method on a type that conforms to Decodable, not on an instance of a type that conforms to Decodable. For example:

    var someString: String = ""
    someString.init(describing: 5) // Not possible, doesn't compile. Can't call an initializer on an _instance_ of String
    var someStringType: String.Type = String.self
    someStringType.init(describing: 5) // Iniitializes a String instance "5"
    

Upvotes: 42

Related Questions