Ok, so I thought I had dropped this question for the night but then while I was just cleaning up formatting I realized that there was a little bit of a pattern here:
type Tag = LensTag | AffineTag | FoldTag;
export type Viewer<T extends Tag, S, A> = {
readonly tag: T;
readonly view: (s: S) => $<ToURI<T>, [A, never, never]>;
};