Typealias of Generic Class in Swift

Generic typealias in Swift

Generic typealias can be used since Swift 3.0. This should work for you:

typealias Parser<A> = (String) -> [(A, String)]

Here is the full documentation: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/typealias-declaration

Usage (from @Calin Drule comment):

func parse<A>(stringToParse: String, parser: Parser) 

What is the purpose of declaring typealias for generic type parameter

Declaring a public typealias makes it possible to access the generic type parameter outside of the closed generic type.

For example if you declare a typealias WidgetFoo = Foo<Widget> and keep using WidgetFoo in other places it will be possible to access its T via WidgetFoo.Element(which refers to Widget) whereas you cannot access the generic type parameter E itself. This enables robust and refactoring friendly code - imagine you want to replace Widget with BetterWidget you only have to change one place (the type alias declaration) and no other because WidgetFoo.Element will then refer to BetterWidget.


Example code (provided by @Airspeed Velocity)

struct S<T> { typealias U = T }

typealias TA = S<Int>

let x: TA.T // 'T' is not a member type of 'TA' (aka 'S<Int>')
let y: TA.U

typealias generic function

Swift 4.1 supports generic type aliases. You can use this feature to provide a name for function with generic parameters.

You may have to use such declaration:

typealias Callback<T> = (Result<T>) -> ()

Extending generic typealias

Please notice that typealiases are just labels for existing types, so this:

extension StringArray {
//Some methods
}

Is the same as this:

extension Array<String> {
//Some methods
}

And that doesn't compile because it is not how extensions work. You must insert the where clause if you want to filter generics. For more information about extensions:
https://docs.swift.org/swift-book/LanguageGuide/Extensions.html

For more information about generic where clauses in extensions: https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID553

How do I define generic typealias for Swift to return specific types of objects?

As mentioned in the comments, T is not defined at class-scope. You need to specify the generic type with the class declaration so it can be used across your class.

Try this:

class PersistentStoreCoordinatorMock<T: NSManagedObject>: Storageable {
var objects = [T]() // here I need to define return array
func findAll(of type: T.Type, predicate: NSPredicate) -> [T] {
findAllWasCalled = true
return objects //here I need to return this when that function was called
}
}

Cast a Swift generic class to a protocol with a typealias

Your return type is impossible in today's Swift. A protocol with an associated type (PAT) is abstract. Applying a where clause doesn't change that. Consider this code:

let x: <WHAT-GOES-HERE?> = test()

What type would x be here? There is nothing you could write there that would compile. What would x.Type return? What you want it to be is Protocol where Protocol.Thing == Int, but that's not a type in Swift. It's a type constraint. That's the only way PATs can be used today. That's why you can't have a property of type CollectionType<Int>, and why you can't write your test() function.

The solution is a type-eraser to convert your protocol into a concrete struct. For example:

protocol Protocol {
typealias Thing
func dosomething() -> Thing?
}
class Class<X>: Protocol {
typealias Thing = X
func dosomething() -> Thing? {
return nil
}
}

struct AnyProtocol<Thing> {
var _dosomething: () -> Thing?
func dosomething() -> Thing? {
return _dosomething()
}
}

func test() -> AnyProtocol<Int> {
return AnyProtocol(_dosomething: Class<Int>().dosomething)
}

It is possible that some future version of Swift would automatically generate these type erasers for you, but I'm not aware of any specific Swift-evolution proposal for one, so we have to write them by hand today.

For more on building and using type erasers, see A Little Respect for AnySequence.

Swift Initialize struct based on typealias

The problem you're seeing stems from the fact that you not haven't constrained the associate type WriterType within JsonProperties.

Currently, it accepts any WriterType type conforming to Writer, regardless of what its Model is.

What you probably want is for the WriterType type to have its Model be the same as the type being conformed to JsonProperties protocol - so you need to constrain it:

protocol JsonProperties: Codable {
associatedtype WriterType: Writer where WriterType.Model == Self
}


Related Topics



Leave a reply



Submit