You can circumvent it. Choose some type, which won't be used in your overloadings. Say, let it be `float`.
template test[T](i: int|float = 0.0)= when i is int: echo "in param" else: echo "no param" test[int]() test[int](1) Or, for it to look less hacky, you may define some special type and value for it: type Nothing = object const nothing = Nothing() template test[T](i: int|Nothing = nothing)= when i is int: echo "in param" else: echo "no param" test[int]() test[int](1)