In javascript, we can create functions on the prototype of existing classes.

Number.prototype.factorial = function() {
  return new Array(this.valueOf())
    .fill()
    .reduce((acc, _, index) => acc * (index + 1), 1);
};

(5).factorial(); // <- 120

However, in typescript, this is not allowed

error TS2339: Property 'factorial' does not exist on type 'Number'.

► file:///C:/Users/lucas/misc/deno_test/main.ts:1:18

1 Number.prototype.factorial = function() {
                   ~~~~~~~~~

We can add // @ts-ignore before every line and this will work, but what if we didn’t want to do that.

Another way is to use eval

eval(
  `Number.prototype.factorial = function() {
  	return new Array(+this).fill().reduce((a, _, i) => a * (i + 1), 1);
   };`
)

This is still allowed in typescript, often codebases lint against eval, as they should. And we will need to use eval("5..factorial()") every time we want to access this.

Since we can import typescript modules in javascript and the other way around, we can create a module that creats our “illegal” method in javascript…

// util.js
export function createIllegalMethod() {
  Number.prototype.factorial = function() {
    return new Array(this.valueOf())
      .fill()
      .reduce((acc, _, index) => acc * (index + 1), 1);
  };
}

…and import it in our typescript modules.

// main.ts
import { createIllegalMethod } from './util.js';

createIllegalMethod();

let foo: number | any = 5;

console.log(foo.factorial());

We still have to use number | any in order for this to compile/run.

Verifying what works in typescript with Deno has made testing this very easy, since it supports typescript out of the box.