code: func ProxyType(L *lua.State) int {
  	if !isValueProxy(L, 1) {
  		L.PushString(L.LTypename(1))
  		return 1
  	}
  	v, _ := valueOfProxy(L, 1)
  
  	pointerLevel := ""
  	for v.Kind() == reflect.Ptr {
  		pointerLevel += "*"
  		v = v.Elem()
  	}
  
  	prefix := "userdata"
  	switch unsizedKind(v) {
  	case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
  		prefix = "table"
  	case reflect.String:
  		prefix = "string"
  	case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Complex128:
  		prefix = "number"
  	}
  
  	L.PushString(prefix + "<" + pointerLevel + v.Type().String() + ">")
  	return 1
  }
docs: // ProxyType pushes the proxy type on the stack.
  //
  // It behaves like Lua's "type" except for proxies for which it returns
  // 'table<TYPE>', 'string<TYPE>' or 'number<TYPE>' with TYPE being the go type.
  //
  // Argument: proxy
  //
  // Returns: type (string)