def get_generic_alias(type_: type) -> type:
    """Get the generic alias for a type.

    Given a type, its generic alias from `typing` module will be returned
    if it exists. For example:

    ```python
    get_generic_alias(list)
    # typing.List

    get_generic_alias(dict)
    # typing.Dict
    ```

    This is mostly useful for python versions prior to 3.9, to get a version
    of a concrete type which supports `__class_getitem__`. In 3.9+ types like
    `list`/`dict`/etc are subscriptable and can be used directly instead
    of their generic alias version.
    """
    if isinstance(type_, _SpecialForm):
        return type_

    for attr_name in dir(typing):
        # ignore private attributes, they are not Generic aliases
        if attr_name.startswith("_"):  # pragma: no cover
            continue

        attr = getattr(typing, attr_name)
        if is_generic_alias(attr) and attr.__origin__ is type_:
            return attr

    raise AssertionError(f"No GenericAlias available for {type_}")  # pragma: no cover
Get the generic alias for a type.

    Given a type, its generic alias from `typing` module will be returned
    if it exists. For example:

    ```python
    get_generic_alias(list)
    # typing.List

    get_generic_alias(dict)
    # typing.Dict
    ```

    This is mostly useful for python versions prior to 3.9, to get a version
    of a concrete type which supports `__class_getitem__`. In 3.9+ types like
    `list`/`dict`/etc are subscriptable and can be used directly instead
    of their generic alias version.
    
strawberry/utils/typing.py