# Safe cast a nullable property based on another property value

**URL:** <https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231>\
**Category:** Language Design\
**Created:** [September 23, 2026, 11:14am UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231 "2026-09-23T11:14:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![MIha\_Markic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/miha_markic/32/11397_2.png) [@MIha\_Markic](https://discuss.kotlinlang.org/u/MIha_Markic)\
**Post date:** [September 23, 2026, 11:14am UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/1 "2026-09-23T11:14:29Z")

</div>

Imagine this class

```kotlin
data class Something(val text: String?) {
  val hasText get() = text != null
}

```

and then this code

```kotlin
val s = Something("something")
if (s.hasText) {
  val text: String = s.text
}

```

Which will fail to compile because one can’t smart cast `String?` to `String` even though it is obvious (to a human) it could.

I wonder whether there is a way to help smart cast being smarter in cases like this. In comparison, C# has few attributes that help with static analysis (i.e. `NotNullWhenAttribute`).

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [September 23, 2026, 12:29pm UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/2 "2026-09-23T12:29:37Z")

</div>

Contracts can get you there, but it’s annoying to write and pollutes your types:

```run-kotlin
import kotlin.contracts.*
data class SomethingT<out Text: String?>(val text: Text)
typealias Something = SomethingT<*>

val Something.hasText get(): Boolean {
  contract { returns(true) implies (this@hasText is SomethingT<String>) }
  return text != null
}

fun main() {
  val s: Something = Something("something")
  if (s.hasText) {
    val text: String = s.text
  }
}

```

The trick is to move the variable-level information (e.g. the nullity of `text`) into a type parameter, so that it’s tracked on the level of `Something` itself and thus can be influenced by contracts on it.

---

<div class="post-metadata">

**Author:** ![MIha\_Markic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/miha_markic/32/11397_2.png) [@MIha\_Markic](https://discuss.kotlinlang.org/u/MIha_Markic)\
**Post date:** [September 23, 2026, 1:13pm UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/3 "2026-09-23T13:13:28Z")

</div>

Hey,

Interesting, thanks. And I agree with you, it pollutes quite heavily. Also it’s not a proper solution, feels more like a hack. I mean what if one has a more complicated class…

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [September 24, 2026, 2:41pm UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/4 "2026-09-24T14:41:04Z")

</div>

This is a pretty contrived example. You could replace `s.hasText` with `s.text != null`. Do you have an actual use case for this?

---

<div class="post-metadata">

**Author:** ![MIha\_Markic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/miha_markic/32/11397_2.png) [@MIha\_Markic](https://discuss.kotlinlang.org/u/MIha_Markic)\
**Post date:** [September 24, 2026, 5:34pm UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/5 "2026-09-24T17:34:54Z")

</div>

It’s a simple sample. What about `data class Result<T>(val valid: Boolean, val result: T?)` or `data class Person(val name: String?, val surname: String?) { val valid: Boolean get() = name != null && surname != null }`.

Then there are functions, like `string? GetTopLevelDomainFromFullUrl(string? url)` where result is not null when url is not null etc.

Read more samples in [C# docs](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/nullable-analysis).

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [September 25, 2026, 2:06am UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/6 "2026-09-25T02:06:19Z")

</div>

I skimmed the article… it does seem like Kotlin’s contracts could replicate some of what C# is doing. I also think that Kotlin’s existing null-handling covers the majority of use cases, so I don’t think that this feature would pass the -100 points rule to warrant adding to the language. But maybe if you’ve got a really specific use case that you’ve experienced where you’ve gone “man there’s really no way to do this in Kotlin like there is in C#”, then I could be convinced. 🙂

---

<div class="post-metadata">

**Author:** ![MIha\_Markic](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/miha_markic/32/11397_2.png) [@MIha\_Markic](https://discuss.kotlinlang.org/u/MIha_Markic)\
**Post date:** [September 25, 2026, 6:25am UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/7 "2026-09-25T06:25:30Z")

</div>

If you look like this, then smart cast is not necessary at all. Why bother when one can do all the `!= null` and type casts by themselves.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [September 25, 2026, 6:43am UTC](https://discuss.kotlinlang.org/t/safe-cast-a-nullable-property-based-on-another-property-value/31231/8 "2026-09-25T06:43:38Z")

</div>

I’d say there’s a big difference between “type casts by hand” and between having to extract properties manually, to then smart cast them normally.  
I’m in agreeance with you that it’d be nice to have smart casts for such properties and be able to have contracts and such for them.

FWIW, I doubt that your original code exactly as written would work. Kotlin prefers functions and properties to be explicit about their guarantees, so something like a property implying something about another would likely be a contract that you’d write out somehow. This is already the case for something like:

```kotlin
val String?.hasNonEmptyText get() = this != null && isNotBlank()

```

which doesn’t provide a smart cast right now because instead you have to write:

```kotlin
val String?.hasNonEmptyText: Boolean get() {
  contract { returns(true) implies (this@hasNonEmptyText != null) }
  return this != null && isNotBlank()
}

```
