Swift Generics: Non-Nominal Type Does Not Support Explicit Initialization

non-nominal type X does not support explicit initialization

You just need to use init explicitly whenever you're initializing a generic parameter rather than a "real" type:

self.c = C.init(modelView: m)

Swift 4: Non-nominal type 'T' does not support explicit initialization

This happens because the compiler doesn't know which initializer it is supposed call, because what you are doing is simply too general, as the error states.
What you are trying to achieve can be done, but the implementation depends on what you are achieve.

In short, if you want to be able to initialize a lot of different types, be it primitives or objects, you should define a new protocol, extend each type to implement this protocol as you see fit and have the T Type restricted to this protocol.

Example:

protocol HTTPHeaderProtocol {
init(_ headerProtocolString: String?)
}

class MyCustomObject: HTTPHeaderProtocol {
var myString = ""
required init(_ headerProtocolString: String?) {
self.myString = headerProtocolString ?? ""
}

}

extension String: HTTPHeaderProtocol {
init(_ headerProtocolString: String?) {
self.init(headerProtocolString)
}
}

extension Int: HTTPHeaderProtocol {
init(_ headerProtocolString: String?) {
self.init(headerProtocolString)
}
}

extension HTTPURLResponse {

func get(_ header: String) -> String? {
let keyValues = allHeaderFields.map { (String(describing: $0.key).lowercased(), String(describing: $0.value)) }

if let headerValue = keyValues.filter({ $0.0 == header.lowercased() }).first {
return headerValue.1
}
return nil
}
func getHeader<T:HTTPHeaderProtocol>(_ httpResponse: HTTPURLResponse, _ headerName: String) -> T? {
guard let element = httpResponse.get(headerName) else {
return nil
}
return T(element)
}
}

This will work, hope that helps:)

Swift generics init: Non-nominal type 'T' does not support explicit initialization

The type system doesn't know, from your list of generics <T: Cacheable, U: RealmObject>, that U is the correct type of RealmObject for T (in other words, you could be passing a Note as T, and an AppointmentObject as U). You just need to update your function signature to:

// The `where T.T == U` is the important part. Because that is defined,
// we can also remove `U: RealmObject` because it's redundant information.
func getCacheable<T: Cacheable, U>(from realmObject: U) -> T where T.T == U {
let thing = T(object: realmObject)
return thing
}

// Alternatively, you can just do:
func getCacheable<T: Cacheable>(from realmObject: T.T) -> T {
let thing = T(object: realmObject)
return thing
}

Swift 4: Non-nominal type 'T' does not support explicit initialization

Here is the error I am getting
Sample Image

Its getting confused with the type(of: and the argument type.

After changing T.Type argument name. Its working :

extension Collection {
/// Finds and returns the first element matching the specified type or nil.
func findType<T>(_ typeT: T.Type) -> Iterator.Element? {
if let index = (index { (element: Iterator.Element) in
String(describing: type(of: element)) == String(describing: typeT) }) {
return self[index]
}
return nil
}
}

Non-nominal type 'User' does not support explicit initialization

The User in your class is not the same as the User type you created. It's just a placeholder for any type. You could replace the word User in your class definition with anything e.g. T or Apple and it would still be the same definition.

The compiler knows nothing about whatinit methods User in your class has, hence the error. To make it work properly, you must constrain the type parameter. This is usually done by making it conform to a protocol e.g.

protocol JSONInitable
{
init(json: JSON)
}

struct User: JSONInitable { ... }
struct Group: JSONInitable { ... }

class LoginTask<PrincipalType: JSONInitable>
{
....

func foo()
{
let user = PrincipalType(json: response)
}
}

In the above, the LoginTask can be used with both User and Group but not any arbitrary type that doesn't conform to the protocol.

Alternatively, if the class will always use the User type, it doesn't need to be generic.

Non-nominal type 'T' does not support explicit initialization Codable

public func getGenericType() -> T.Type {
return T.self
}


Related Topics



Leave a reply



Submit