Feature Request: Typealias for expected Types

I have a use case where I only need to pass an object through shared code. The object is created in platform specific code and only used in platform specific code, but in another layer.

The only solution I found was to create a wrapper object, which implements the expected class.
It’s really annoying to get an object for example Uri / NSUrl and to wrap it in another object, pass it through shared code without use until I finally need to unwrap it again for use.
I think this could often happen when using libraries in platform specific code like firebase, which are using types of the android or iOS SDK.

Something like
expect typealias CommonUrl
would be great, because in platform specific code we are already able to replace CommonUrl with Uri.

3 Likes

I like the idea, not the example:

generic classes

Typealias itself can be supported already:

expect class CommonUrl

Now you can impement it with a typealias:

// iosMain
actual typealias CommonUrl = NSUrl
// androidMain
actual typealias CommonUrl = Uri

Example

We currently have to define if something is a class/interface in the common-codebase.
When we have an interface in one and a class in the other, we have to write wrappers.
(Or is this impossible//already implemented?)

3 Likes

Thanks for your reply.
However, your example is not working.
Uri and NSURL are too different. Uri has an private constructor and is constructed by a static factory method. NSURL has several overloaded constructors so i need to call at least one of them.

expect class

commonMain

// has a public no argument constructor 
// is instantiable by primary constructor  
expect class CommonUrl

androidMain

// is not working, because there is no public constructor
// is not instantiable or only instatiable by static factory method
// Error: Actual typealias 'CommonUrl' has no corresponding expected declaration
// The following declaration is incompatible because modality is different
actual typealias CommonUrl = Uri

iosMain

// is not working, because there is no no-arg constructor which could be called
// Error: Conflicting overloads
actual typealias CommonUrl = NSURL

expect interface

commonMain

expect interface CommonUrl()

androidMain

// Error: Actual typealias 'CommonUrl' has no corresponding expected declaration 
// The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation)
actual typealias CommonUrl = Uri

iosMain

// Error: Conflicting overloads
actual typealias CommonUrl = NSURL
1 Like

expect class CommonUrl doesn’t have a no-arg constructor. In order to have it, an expect class should declare it explicitly, like following: expect class CommonUrl().
Though there are other limitations which prevent such actualization. In Android, Uri is an abstract class, and an abstract class cannot currently actualize a final/open class.

Sometimes you can suppress an error about incorrect actualization with @Suppress("ACTUAL_WITHOUT_EXPECT"). Note however, that suppressing errors in general is a dangerous approach, it can subsequently lead to a compiler exception or an incorrect program being compiled.

1 Like

What about something like expect typealias Foo. That way we could declare that we want to have a type Foo but don’t care what it is. This means that common code would only be able to store and pass those types around and not interact with them otherwise. I think that is what the OP was looking for.

8 Likes

I have encountered similar problems. Are there any follow-ups on this topic in 2023? For example maybe an issue in YouTrack?