Composing CaseKeyPaths and KeyPaths #127
-
Thanks to the new macro implementation, CaseKeyPaths are naturally composable via dot syntax just as KeyPaths, but when trying to compose CaseKeyPaths with normal KeyPaths unfortunately the compiler errors out. @CasePathable
enum PaymentType {
case creditCard(CreditCard)
}
struct CreditCard {
var number: String
// ...
}
\PaymentType.Cases.creditCard.number // 🛑 Generic parameter 'AppendedValue' could not be inferred
// 🛑 Subscript 'subscript(dynamicMember:)' requires that 'CreditCard' conform to 'CasePathable' Is this a technical limitation that can't be circumvented, or something pending to be implemented in the future perhaps? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
@davdroman Just curious, what is your expectation with the above path and how would you like it to be used? |
Beta Was this translation helpful? Give feedback.
-
I stumbled upon this recently, as I found myself also trying to make use of a generic WriteableKeyPath, where the some elements of the path included enums. The use case I have, is that in a hyper modular project, using TCA, imagine we have a child feature module, which is composed by two different ancestor modules. When we write the tests for the ancestor feature, we want to strike a balance between exhaustive testing, but also readable and maintainable code. To this end, it's useful to provide Test Helper modules alongside the child feature module which the test targets of dependent modules can make use of. These test modules might expose functions like public func assertChildFeature<State: Equatable, Action: Equatable>(
in store: TestStore<State, Action>,
state: WritableKeyPath<State, ChildFeature.State?>,
action: CaseKeyPath<Action, ChildFeature.Action>,
behaviour: String,
expectedResult: TaskResult<Bar>
) async We need the state and action paths - because the child feature does not know how it has been integrated into any ancestor. And But, anyway, it seems that if the state is composed using any enum state - then this cannot be achieved, because - as you point out, we cannot write the complete associated type of an enum if the key path is further refined. I think, the only options for a mixed case like this, is to provide a function which returns an inout assertion closure. So the test helper can execute this function, and provide the assertion. |
Beta Was this translation helpful? Give feedback.
@davdroman Both of the examples above are maybe too concrete to get at the meat of the issue, so I'd be curious if you have a sketch of how you were trying to use
Scope
.One thing to note is that for access, if you use
@dynamicMemberLookup
you can get a key path to the underlying thing:For setting into the thing it's more complicated. Remember that case paths can unconditionally embed. So say that theoretically
\PaymentType.Cases.creditCard.number
returned aCaseKeyPath<PaymentType, String>
. The …