Action represents a generic function. A generic function implies it can be called with any type that satisfies the type constrained for a given type parameter.
So this code compiles without any issues:
declare const action: Action;
action({ count: 0 }); //should return {count :number }
action({ sum: 0 });//should return {sum :number }
action({ msg: "Some text" });//should return {msg:number }
The problem is that your function (at least according to it's signature) does not satisfy this requirement. It takes in a state and returns a state. As highlighted above the requirements of action make it more flexible.
If your function is truly just an identity function you can just use any to make the function compatible with the signature
const action: Action = (state: any) => state
Or you can make the function implementation generic:
const action: Action = <T>(state: T) => state
If what you want is not a generic function (ie a function that works for any T) but a regular function with a signature that can be customized for a given type, you need to put the type argument on Action:
type Action<S> = (state: S) => S
type Dispatch = <A extends Action<any>>(action: A) => void
const dispatch = (action: Action<any>) => { }
const action: Action<IState> = (state) => state
//declare const action: Action;
action({ count: 0 });
action({ sum: 0 }); // error
action({ msg: "Some text" }); // error
dispatch(action)