static <T extends Type> String getTypeName(TypeReference<T> typeReference) {
        try {
            java.lang.reflect.Type reflectedType = typeReference.getType();

            Class<?> type;
            if (reflectedType instanceof ParameterizedType) {
                type = (Class<?>) ((ParameterizedType) reflectedType).getRawType();
                return getParameterizedTypeName(typeReference, type);
            } else if (typeReference.getSubTypeReference() != null) {
                return getParameterizedTypeName(typeReference, typeReference.getClassType());
            } else {
                type = Class.forName(getTypeName(reflectedType));
                if (StructType.class.isAssignableFrom(type)) {
                    return getStructType(type);
                }
                return getSimpleTypeName(type);
            }
        } catch (ClassNotFoundException e) {
            throw new UnsupportedOperationException("Invalid class reference provided", e);
        }
    }
@Test
    public void testGetTypeName() {
        assertEquals(Utils.getTypeName(new TypeReference<Uint>() {}), ("uint256"));
        assertEquals(Utils.getTypeName(new TypeReference<Int>() {}), ("int256"));
        assertEquals(Utils.getTypeName(new TypeReference<Ufixed>() {}), ("ufixed256"));
        assertEquals(Utils.getTypeName(new TypeReference<Fixed>() {}), ("fixed256"));

        assertEquals(Utils.getTypeName(new TypeReference<Uint64>() {}), ("uint64"));
        assertEquals(Utils.getTypeName(new TypeReference<Int64>() {}), ("int64"));
        assertEquals(Utils.getTypeName(new TypeReference<Bool>() {}), ("bool"));
        assertEquals(Utils.getTypeName(new TypeReference<Utf8String>() {}), ("string"));
        assertEquals(Utils.getTypeName(new TypeReference<DynamicBytes>() {}), ("bytes"));
        assertEquals(
                Utils.getTypeName(new TypeReference<StaticArray32<Uint256>>() {}), ("uint256[32]"));

        assertEquals(
                Utils.getTypeName(
                        new TypeReference.StaticArrayTypeReference<StaticArray<Uint>>(5) {}),
                ("uint256[5]"));
        assertEquals(Utils.getTypeName(new TypeReference<DynamicArray<Uint>>() {}), ("uint256[]"));
    }