HandlebarsApplicationMixin Usage from the foundry-vtt-types node package
I have recently started to use foundry to dm my games and as a programmer myself I have been building macros and simple module stuff for the last few weeks. I am newish to type script since I use C++ mostly for my work, so I am a bit lost here. How am I supposed to use HandlebarsApplicationMixin? Every time I try to extend my custom class with HandlebarsApplicationMixin(DocumentSheetV2), I get an error that says no base constructor has the specified number of type arguments. I know C++ knowledge doesn’t transfer directly, but it seems to just be a generic type definition so why would it have a constructor error?
Solution:Jump to solution
You can see the generic parameters for
DocumentSheetV2
at its definition:
```ts
declare class DocumentSheetV2<
Document extends foundry.abstract.Document.Any,
RenderContext extends AnyObject = EmptyObject,...29 Replies
Hey, I don't check the #package-development threads as often since usually TypeScript questions go in #typescript.
regardless, you're saying that just
HandlebarsApplicationMixin(DocumentSheetV2)
is giving this error?Ah that’s my bad I just joined the server and didn’t see that
not a problem
just pointing out that I have #typescript set up to ping me, it's just chance that I saw this so fast by comparison
ESLint is erroring saying “no base constructor has the specified number of type arguments”
Using latest version of the master branch btw for the types
I think you probably mean
main
but yes main
is for v12 beta right nowRight old habits
so you got the right branch
not a problem
just wanted to make sure we were talking about the same branch
in case you were actually on, idk, actual master somehow (which would be very very old by now)
Yeah so the issue is that
DocumentV2
requires generic parameters
dumb error message, absolutely, but asfik there's no way to make a friendlier error here
you can see in this example usage that HandlebarsApplicationMixin(DocumentSheetV2)<...>
is written
the parameters in the <...>
"pass-through" the mixin to DocumentSheetV2
Solution
You can see the generic parameters for
DocumentSheetV2
at its definition:
Ahhh gotcha thank you so much. Been such a mental pain going from a strongly typed language to this. The fact it is sort of typed makes me think in c++ terms so I keep messing stuff up.
by most accounts TypeScript is still strongly typed
of course its types don't exist at runtime and unfortunately there's a bunch of unsoundness
if you want to think about what's going on in C++ terms, we've basically passed a template through a function (though in C++ you can't pass a template to a function so you'd have to make the 'function' a macro or a template itself asfik)
since we didn't provide any of the parameters to this template, we still have to provide them somehow
hence
HandlebarsApplicationMixin(DocumentSheetV2)<...>
is basically equivalent to HandlebarsApplicationMixin(DocumentSheetV2<...>)
... but this second more intuitive version isn't valid for annoying reasonsGotcha. Makes a lot more sense now thank you. Though when I put the <…> at the end it errors saying it expected a type lol is that something with my tsconfig maybe?
can you copy and paste exactly what you're trying to write?
like
class YourClass extends ... {}
with the minimum context required?
I don't care what's in the class body itselfexport class EffectConfig extends HandlebarsApplicationMixin(DocumentSheetV2)<…> {}
ah so when I wrote
<...>
I meant ...
as "fill in here" not as a literal syntactic constructAhh sorry I misunderstood this as some sort of typescript syntax called “passthrough”
yeah understandable
you can see an example here,
DocumentSheetV2
takes 4 generic parameters, Document
, RenderContext
, Configuration
, and RenderOptions
most people only care about Document
and RenderContext
, fortunately Configuration
and RenderOptions
are optionalOk thanks that is working fine now.
RenderContext
is what's returned by _prepareContext
Document
should hopefully be pretty intuitiveGotcha I think I’ve seen that in some of the examples online I’ve been looking at. Mostly been learning by looking at other modules, though some are not in typescript so I sorta have to translate it.
right
there are a few systems out there written in TypeScript but we'll have better docs before fvtt-types v12 gets out of beta
to explain the original error btw, to get it you have to either be using some complex mixin stuff (what we're doing) or use an archaic way of defining classes:
you'll get the same error here
it's fundamentally the same thing as you get with this:
but this gives the nicer error
Generic type 'Foo<T>' requires 1 type argument(s).
in both cases Foo
is the "base constructor" because in both cases Foo
is a constructor (something you can run new
on, so like a class)
and "base" because it's what you're trying to extend
so it's saying "what you're trying to extend doesn't have the number of arguments you're trying to pass" which in your case was 0
unintuitive for sure!Hmmm alright. It’ll take some getting used to but I’ve only spent about a week learning all this. Ran a few sessions using some of the already made modules, but I felt a lot of inconsistency in how I actually wanted the game to act so decided it would be better to learn it myself. Hopefully a few more weeks and I won’t be as lost 😂
haha
feel free to pop into #typescript with any questions
Thanks. I’ll mark this as solved when I get back to my computer
also if you have any areas that aren't built out yet in fvtt-types just let us know
I like to prioritise things people are actually using
but there's known patterns that don't work yet like
xyz.update({ "some.dot.key": 2 })
Gotcha thanks. I’ll definitely reach out if I find something. So far though it is working great
that's the hope
if you run into any "circular errors" which are of the form "... referenced directly or indirectly ..." or "... excessively deep ..."
these tend to be the hardest to diagnose yourself
and it's only been until recently that I can say there's only 1 of those left in fvtt-types itself
Haha alright I’ll remember that. Sounds comparable to the horrors of segfaults
at least you get coredumps for that
and sanitizers etc.
True