Это интересная проблема.Немного поиграв с этим, я думаю, что нашел сигнатуру, которая имеет правильное поведение:
declare function execute<P>(action: Action<any> & Action<P>, payload: P): void;
Тип пересечения, кажется, задерживает оценку Action<P>
до тех пор, пока не будет выведено P
:
execute(testFn, ''); // okay
execute(testFn, 123); // error, 123 is not a string
Я действительно не знаю, почему это происходит (возможно, кто-то, более знакомый с внутренностями компилятора, может сказать что-то лучше здесь), но, может быть, этого достаточно, чтобы помочь вам добиться прогресса?Удачи!