I'm drafting an API implementation, started with a...
# announcements
c
I'm drafting an API implementation, started with a model like this:
Copy code
abstract class UnsignedRequest {
  abstract fun signatureData(): String
  fun <T : UnsignedRequest> sign(signer: (String) -> Signature): SignedRequest<T> =
    SignedRequest(unsignedRequest = this as T, signature = signer(signatureData()))
}

data class SignedRequest<T : UnsignedRequest>(
  @JsonUnwrapped val unsignedRequest: T,
  val signature: Signature
}
Is there a way to make
sign
method type-safe? I really don't like the unchecked cast to the type parameter:
this as T
. So far I came up with this, which is at least type safe, but repetitive, as I'm essentially copying the signing logic:
Copy code
interface UnsignedRequest {
	fun signatureData(): String
	fun sign(signer: (String) -> Signature): SignedRequest<*>
}

data class SignedRequest<T : UnsignedRequest>(
  @JsonUnwrapped val unsignedRequest: T,
  val signature: Signature
}

data class ActualUnsignedRequest(/* properties */) {
  override fun signatureData(): String = /* some composition of properties */
  override fun sign(signer: (String) -> Signature) : SignedRequest<ActualUnsignedRequest> =
    SignedRequest(req = this, signature = signatureData().let(signer))
}
UPDATE: Silly me 😄 Forgot about extension functions' awesomeness!
Copy code
inline fun <T : UnsignedRequest> T.sign(signer: (String) -> String): SignedRequest<T> =
	SignedRequest(req = this, signature = signatureData().let(signer))