Can't access p5.Vector methods in typescript, like random2D() and sub()

The statement import * as p5 from "p5"; makes p5 available as a datatype, but not as the actual p5 constructor.

That is, you can only use p5 to describe things like this after a colon:

  • constructor(p5: p5, x: number, y: number) {
  • behaviors(p5: p5) {
  • pos: p5.Vector;

And if you attempt to access it like this:

  • p5.Vector.random2D();
  • p5.Vector.sub(target, this.pos);
  • new p5(sketch);

It implies that p5 comes straight from the import statement.

However that’s not true, b/c p5 is already available in the global context right after it’s fully loaded within an HTML file:
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>

Unfortunately, for unknown reasons, the package “@types/p5” fails to tell that to the TypeScript compiler.

So from TypeScript’s PoV, library “p5.js” is a module that must be imported rather than a JS regular library which makes itself globally available as property p5.

Luck for you I used to have those same errors and I’ve been forced to code a solution for it already.

It’s a “.d.ts” file which we don’t have to import it, but merely use the triple-slash directive syntax instead:
/// <reference path="../typings/p5-global.d.ts" />

“p5-global.d.ts” describes another p5 constructor that’s exclusively accessed via the window object:

  • window.p5.Vector.random2D();
  • window.p5.Vector.sub(target, this.pos);
  • new window.p5(sketch);

Therefore we can normally continue using p5 as a datatype.

And then switch to window.p5 only when we need to access the real p5 namespace.

I’ve converted & refactored the original “059_Steering_Text_Paths” to TS as an ES6 module instance mode sketch:

You can watch it running online by clicking on this link.

And also download the whole project from here:

6 Likes