-
Notifications
You must be signed in to change notification settings - Fork 56
Hooks
The league types come with type definitions for the various hooks that Foundry VTT provides and also a way to register your own hook callback types. For foundry V9, the types also offer a way to register custom error
hook callback types.
In general all hooks are typed here. This file should be the go-to source, if you want to find out about certain hooks.
Some of the usage is already documented in the above linked file on the Hooks
namespace. Type-wise there are two kinds of hooks in Foundry versions 8 or older and three kinds in 9 and newer:
- static hooks (with static names)
- dynamic hooks (with names composed at runtime)
-
error
hook (V9+, with parameter types discriminatable on the first parameter)
Using these is easy, you only have to provide the name of the hook as first parameter to Hooks.on
or Hooks.once
and the types of the callback are automatically picked correctly:
Hooks.on("updateWorldTime", (worldTime, dt) => {
worldTime; // number
dt; // number
// [...]
});
This is a a bit less straight forward, as it requires you to provide a generic type parameter to Hooks.on
or Hooks.once
. For example like this:
Hooks.on<Hooks.CloseApplication<FormApplication>>("closeFormApplication", (app, jq) => {
app // FormApplication
jq // JQuery
// [...]
});
Most of the time, the name of the hook has to include the name of the class that you want to call the hook for. So the hook name and the generic type parameter should fit together. Pay attention to the documentation either in the linked file or in the official Foundry API documentation. In most cases this is documented in the official API documentation as well.
The error
hook callback works mostly like a static hook. You can discriminate the error
hook parameter types by the value of the first parameter. Though to achieve this, you have to specify the parameters of the hook as rest parameters (for example ...args
). This is a limitation in typescript, where type discrimination can only be done on single variables and not on disjointed parameters.
Hooks.on("error", (...args) => {
if (args[0] === "Canvas#draw")
args[2].layer // CanvasLayer
// [...]
})
You can register you own custom hook callback types for static hooks by declaration merging into the interface Hooks.StaticCallbacks
like so:
declare namespace Hooks {
interface StaticCallbacks {
fooBar: (baz: string, bar: number) => boolean;
}
}
Your custom hook can then be accessed like this:
Hooks.on("fooBar", (baz, bar) => {
baz; // string
bar; // number
return true;
});
Extending the dynamic callback types is currently not possible.
You can register you own custom error
hook callback parameters by declaration merging into the interface Hooks.ErrorCallbackParameters
like so:
declare namespace Hooks {
interface ErrorCallbackParameters {
"MyClass#myMethod": [location: "MyClass#myMethod", err: Error, data: { foo: number }];
}
}
The key name doesn't matter, only the value of the location
tuple entry does. You can then access it like this:
Hooks.on("error", (...args) => {
if (args[0] === "MyClass#myMethod")
args[2].foo; // number
});
You can also overwrite any of the Foundry specific error
callback parameter types by declaration merging over the corresponding key in the interface.