I found a way to deal with the problem finally. We cannot define an template which return an 'type' (sometime it will fail to compile), but if I return a variable of the type, it is ok, then I can get the type of the variable.
template get_val_from_item(seq1: untyped): untyped =
   var result: type((when compiles(seq1.len): seq1[0] elif seq1 is Slice: seq1.a else: seq1))
   result

template foo1(t: untyped) =
   var x: type(get_val_from_item(t))

proc foo[T](x: seq[seq[T]]) =
   foo1(x)
   echo x
2017-05-12 00:43:47
You're right, your module's getType was used. Just to be used in type annotations it should not be immediate - should either have typed arguments or be overloaded. Adding some proc (template, ...) like proc getType = discard makes import macros unneeded - that was just coincidence, that it has the same-named procedure, making your template overloaded.
2017-05-12 09:54:00
<<<••12••>>>