Here's a minimal example of some typescript code:
// codebase.ts
console.log(document.body.shadowRoot);
console.log(document.body.childNodes);
It is proposed that we add the following functions:
// utils.ts
function shadowRoot(n: HTMLElement) {
// SNIP, check for monkeypatching and maybe return a 'pure' version instead
return n.shadowRoot;
}
function childNodes(n: HTMLElement) {
// SNIP, check for monkeypatching and maybe return a 'pure' version instead
return n.childNodes;
}
And make extensive changes throughout the codebase as follows:
// codebase.ts
+import { shadowRoot, childNodes } from 'utils';
-console.log(document.body.shadowRoot);
-console.log(document.body.childNodes);
+console.log(shadowRoot(document.body));
+console.log(childNodes(document.body));
The point of these functions is to ensure that we are using 'pure' versions of the underlying DOM functions in the case that they have been monkeypatched via 3rd party code; so as such we don't really want to try to monkeypatch them again.
The correct javascript output is as follows:
"use strict";
function shadowRoot(n) {
// implementation omitted
return n.shadowRoot;
}
function childNodes(n) {
// implementation omitted
return n.childNodes;
}
console.log(shadowRoot(document.body));
console.log(childNodes(document.body));
My question is whether it is possible to do this transformation as an optional build step, without having to modify codebase.ts?
Without having to ensure that no future developers (or ourselves) regresses and adds code which directly accesses these particular attributes.
Edit: there is a rollup plugin which will do a regex replace, but I don't think that will be robust enough to transform e.g.
- const shadowRoot = (n as HTMLElement).shadowRoot;
+ const shadowRoot = shadowRoot((n as HTMLElement));
ts-patch. Seen as your doing this to remove monkey patching, it would seem strange then to monkey patch typescript. Be aware this might break in the future likettypscriptit replaced. Typescript having proper plugin support would have been nice..