Convert between type hints of `Protocol` and `Callable`?

Given following example:

from typing import Protocol, Callable

class Domain(Protocol):
    def foo(self, arg: str) -> str:
    def bar(self, arg: int) -> int:

# how to infer this type hint from Domain?
FooFn = Callable[[str], str]
  1. What is the recommended way - if possible - to extract method signatures of foo and bar into a separate Callable type, while leaving out the self-referential context?
  2. Is it possible to inverse this operation, i.e. incorporate a function Callable into a Protocol?


I am using Protocols for objects which are to be constructed via dependency injection. All methods need the same set of dependencies, so it makes sense to set them up this way. Now sometimes I’d like to limit methods of Domain depending on the client and make only one of them available (interface segregation).

It is possible to separate all methods:

class Foo(Protocol):
    def foo(self, arg: str) -> str: ...

class Bar(Protocol):
    def bar(self, arg: int) -> int: ...

class Domain(Foo, Bar, Protocol): ...

, but I would like to just pass a function with help of closures instead of an object with one method type:

def client(foofn: FooFn):

# instead of 
def client(myfoo: Foo):

TypeScript for example can leverage lookup types, Parameters or ReturnType for call signatures:

type Foo = {
    foo: (arg: string) => string
type T1 = Foo["foo"] // (arg: string) => string
type T2 = Parameters<T1> // [arg: string]
type T3 = ReturnType<T1> // string

I discovered Concatenate for Python, and tried to use it for this case, but this seems to rather suited for HOCs.