@Observable doesn't work for classes defined inside an extension

Hey,

I love the new @Observable macro! However, I just hit a small inconvenience with it. When you apply it to a class that's defined inside an extension, the code doesn't compile anymore:

@Observable class Foo {} // Compiles fine

extension Foo {
    @Observable class Bar {} // Does not compile
}

In fact, the compiler doesn't even give you a proper error message, it just fails with a generic "Command SwiftCompile failed with a nonzero exit code" in Xcode 15 Beta 1.

I guess this happens because the macro adds the Observable conformance via an extension, which needs to be in top-level code, right?

// ... (Other synthesized code)
extension Bar : Observable  {}

Is there a way around this problem? Nesting types is the only real way of "namespacing" things in Swift.

Thanks!

6 Likes

I don't know if there is a workaround. But another way to use name-spaces is by modularizing your app.

For example:
If you have a module called Foo, with a target with the same name, and it has a class like this:

@Observable class Bar {}

You can import it in another module/target and use it like this:

import Foo

Foo.Bar

Separating your app in modules, will also help you to have previews without compiling the whole app.

I saw yesterday that this has been reported. Thanks.
Extensions for subtype of a class marked @Observable generate compile error · Issue #66450 · apple/swift · GitHub

In the meantime, I've gone back to the old hack of putting an underscore in, until things work. E.g. Foot_Bart rather than Foot.Bart.

Looks like a different issue.