from typing import AsyncIterator, Awaitable, Callable, overload

from ._typing import AnyIterable, T, LT

@overload
def merge(
    *iterables: AnyIterable[LT], key: None = ..., reverse: bool = ...
) -> AsyncIterator[LT]: ...
@overload
def merge(
    *iterables: AnyIterable[T], key: Callable[[T], Awaitable[LT]], reverse: bool = ...
) -> AsyncIterator[T]: ...
@overload
def merge(
    *iterables: AnyIterable[T], key: Callable[[T], LT], reverse: bool = ...
) -> AsyncIterator[T]: ...
@overload
async def nlargest(
    iterable: AsyncIterator[LT], n: int, key: None = ...
) -> list[LT]: ...
@overload
async def nlargest(
    iterable: AsyncIterator[T], n: int, key: Callable[[T], Awaitable[LT]]
) -> list[T]: ...
@overload
async def nlargest(
    iterable: AsyncIterator[T], n: int, key: Callable[[T], LT]
) -> list[T]: ...
@overload
async def nsmallest(
    iterable: AsyncIterator[LT], n: int, key: None = ...
) -> list[LT]: ...
@overload
async def nsmallest(
    iterable: AsyncIterator[T], n: int, key: Callable[[T], Awaitable[LT]]
) -> list[T]: ...
@overload
async def nsmallest(
    iterable: AsyncIterator[T], n: int, key: Callable[[T], LT]
) -> list[T]: ...
