Here’s one case where I would like to use default types for generics:
fun <TId> item(lambda: DlgTextItemDef<TId>.() -> Unit) =
DlgTextItemDef.build(lambda)
In my scenario it is very common that items have no id, but I have to write item<Unit> everywhere. I tried with an overload:
fun item(lambda: DlgTextItemDef<Unit>.() -> Unit) =
DlgTextItemDef.build(lambda)
fun <TId> item(lambda: DlgTextItemDef<TId>.() -> Unit) =
DlgTextItemDef.build(lambda)
This does not compile, because it generates a naming clash on the JVM. I tried inlining it, but the compiler still complains:
inline fun <reified Id> item(noinline lambda: DlgTextItemDef<Id>.() -> Unit) =
DlgTextItemDef.build(lambda)
This forces me to either be happy with item<Unit>, or use a different name for the rare use case, i.e. itemWithId. But the latter is ugly, because there are already overloads:
fun <Id> item(lambda: DlgTextItemDef<Id>.() -> Unit) =
DlgTextItemDef.build(lambda)
fun <Id> itemWithBooleanValue(lambda: DlgBooleanItemDef<Id>.() -> Unit) =
DlgBooleanItemDef.build(lambda)
fun <Id> itemWithIntValue(lambda: DlgIntItemDef<Id>.() -> Unit) =
DlgIntItemDef.build(lambda)
fun <Id> itemWithFloatValue(lambda: DlgFloatItemDef<Id>.() -> Unit) =
DlgFloatItemDef.build(lambda)
So I would end up with itemWithBooleanValue, itemWithBooleanValueWithId, etc. Clearly, the following would be the best solution:
fun <Id = Unit> item(lambda: DlgTextItemDef<Id>.() -> Unit) =
DlgTextItemDef.build(lambda)
TypeScript can do it, so why can’t Kotlin?