user3096733 user3096733 - 1 year ago 836
Swift Question

Generic parameter T could not be inferred. Factory methods

Can someone explain to me why this wouldn't work?

I have a class with factory methods like this:

public class NetworkTask<T> {

var request: URLRequest

var completionHandler: NetworkResponse<T> -> Void

init(request: URLRequest, completionHandler: NetworkResponse<T> -> Void) {

self.request = request
self.completionHandler = completionHandler

static func dataResponseTaskWithRequest(request: URLRequest, completionHandler: NetworkResponse<NSData> -> Void) -> NetworkTask<NSData> {

return NetworkTask<NSData>(request: request, completionHandler: completionHandler)

static func mappedObjectResponseTaskWithRequest<MappedType>(request: URLRequest, completionHandler: NetworkResponse<MappedType> -> Void) -> NetworkTask<MappedType> {

return NetworkTask<MappedType>(request: request, completionHandler: completionHandler)

Then, after happily knowing that it compiles, I go to create a Task like this:

let task = NetworkTask.dataResponseTaskWithRequest(URLRequest()) { (response) in



Generic parameter T could not be inferred

Wait, I can clearly infer it, the method returns
, so T is NSData.

Ok... then, maybe like this?

let task: NetworkTask<NSData> = NetworkTask.dataResponseTaskWithRequest(URLRequest()) { (response) in



Cannot invoke 'dataResponseTaskWithRequest' with an argument list of type '(URLRequest, (_) -> _)'

Ok, so maybe the other method:

let task = NetworkTask.mappedObjectResponseTaskWithRequest(URLRequest()) { (response: NetworkResponse<String>) in



Cannot convert value of type '(NetworkResponse) -> ()' to expected
argument type 'NetworkResponse<_> -> Void'

I must be clearly missing something here because the compiler can't have so many errors. Does anybody have any clue?

mz2 mz2
Answer Source

NetworkTask<T> is the type, not NetworkTask. That is, the parameter T is on the class and everything you do with that class, also to access its class methods, require describing that type.

Even though the T is not included in the method declaration that gives you the compiler error, there is no class NetworkTask that would contain all the class methods where the type parameter is not included – imagine instead that the method is on all classes NetworkTask<T> for any value of T. This is similar to C++ where the corresponding is even called "template", meaning that your class declaration with generic type parameters is used as a template for literally compiling different classes. This is different to for instance Java where the generics syntax is just compile time sugar with type erasure (you could indeed there call the class method – only one class really exists in that case).

Here's a minimal example to demo this some more:

class A<T> {
    class func foo() {

    class func bar(t:T) -> Void {

class B {} // this gives an error because the type cannot be inferred. // this works fine without compiler errors as the integer literal type can be inferred there.

In the example case above, A would be fine to called for instance with:


You should perhaps consider whether the methods in this case belong in the class that has that type parameter T, or whether they should have something else as a receiver (or indeed whether they should be free functions?).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download