how can mapped function parameters be constrained without being redefined?

You can try

type Typed<T> = T extends number | string? {[topic: string]: (message: T ) => void } : never;

TopicToValue extends Typed<number|string>;