def traverse(
        self,
        predicate: Callable[[Union[IndexObjUnion, TraversedTreeTup], int], bool] = lambda i, d: True,
        prune: Callable[[Union[IndexObjUnion, TraversedTreeTup], int], bool] = lambda i, d: False,
        depth: int = -1,
        branch_first: bool = True,
        visit_once: bool = False,
        ignore_self: int = 1,
        as_edge: bool = False,
    ) -> Union[Iterator[IndexObjUnion], Iterator[TraversedTreeTup]]:
        """For documentation, see
        `Traversable._traverse() <git.objects.util.Traversable._traverse>`.

        Trees are set to ``visit_once = False`` to gain more performance in the
        traversal.
        """

        # # To typecheck instead of using cast.
        # import itertools
        # def is_tree_traversed(inp: Tuple) -> TypeGuard[Tuple[Iterator[Union['Tree', 'Blob', 'Submodule']]]]:
        #     return all(isinstance(x, (Blob, Tree, Submodule)) for x in inp[1])

        # ret = super().traverse(predicate, prune, depth, branch_first, visit_once, ignore_self)
        # ret_tup = itertools.tee(ret, 2)
        # assert is_tree_traversed(ret_tup), f"Type is {[type(x) for x in list(ret_tup[0])]}"
        # return ret_tup[0]

        return cast(
            Union[Iterator[IndexObjUnion], Iterator[TraversedTreeTup]],
            super()._traverse(
                predicate,  # type: ignore[arg-type]
                prune,  # type: ignore[arg-type]
                depth,
                branch_first,
                visit_once,
                ignore_self,
            ),
        )
For documentation, see
        `Traversable._traverse() <git.objects.util.Traversable._traverse>`.

        Trees are set to ``visit_once = False`` to gain more performance in the
        traversal.
        
git/objects/tree.py