It is currently rather difficult to write custom transaction types because transaction types are implemented as class constants rather than subclasses. See the `PhabricatorTransactions` class, for example.
We have previously had similar issues with edges and PHIDs, both which were solved by moving to subclasses rather than class constants (see D6502 and D9837).
See discussion in D14481. There's probably also some discussion on the modularization of PHID and edge types in T2715 and T5245, respectively.