export type Op = string | { op: string; a: Op; b: Op }; export type Rewrite = { type: 'rewrite'; left: left; right: right; }; export type Flip> = Rewrite; export type ApplyRewrite> = O extends R['left'] ? R['right'] : O extends string ? O : O extends { a: Op, b: Op, op: string } ? ( ApplyRewrite extends O['a'] ? Omit & { b: ApplyRewrite } : Omit & { a: ApplyRewrite } ) : never; // interface Kind { // _: V; // return: unknown; // } // type Ap = (K & { _: V })['return']; export type ChainRewrites[], O extends Op> = Rws extends [] ? O : Rws extends [infer R extends Rewrite, ...infer Rs extends Rewrite[]] ? ChainRewrites> : never;