Developing further Araq's idea you can try this hacky one:
template IndexedContainerElementType(a: typedesc): typedesc =
when a is openarray:
type((proc(v: a): auto = v[0])([]))
else:
type(cast[ptr a](nil)[][0])
type
MyChar = IndexedContainerElementType(string)
MyInt = IndexedContainerElementType(seq[int])
proc foo(a: openarray[int]) =
type ElemType = IndexedContainerElementType(type(a))
var b: ElemType
b = 123
echo b
Not exactly "inside", but in a nim way. E.g.
type MyContainerTemplate[T] = object
elements: seq[T]
# Return type of this pseudo-proc will mean the element type.
proc getElemTypeHelper[T](a: typedesc[MyContainerTemplate[T]]): T = discard
# Public API
template ElemType(t: typedesc[MyContainerTemplate]): typedesc =
type(t.getElemTypeHelper)
# Test
type MyContainer = MyContainerTemplate[int]
type MyContainerElemType = MyContainer.ElemType
I'm not sure, however, if such exercises would be "canonical" Nim. Usually there are ways to do it more straightforward. But if you're just investigating the limits of Nim, you have to seek further ;)