Typing utilities#
registerUtility, getUtility, and getUtilities now bind their method signatures to the utility type. You can declare the expected method shape for a given type using the UtilityTypeMap interface from @plone/types.
Declare utility method types#
Extend UtilityTypeMap via module augmentation (for example in src/types/volto.d.ts):
// src/types/volto.d.ts
declare module '@plone/types' {
interface UtilityTypeMap {
rootContentSubRequest: (options: { path: string }) => Promise<unknown>;
// Add more utility types here
}
}
Typed registry usage#
Once declared, utilities of that type are strongly typed:
import config from '@plone/registry';
config.registerUtility({
name: 'rootContent',
type: 'rootContentSubRequest',
method: async ({ path }) => fetch(path).then((res) => res.json()),
});
const { method } = config.getUtility({
name: 'rootContent',
type: 'rootContentSubRequest',
});
// method is (options: { path: string }) => Promise<unknown>
method({ path: '/news' });
getUtilities({ type: 'rootContentSubRequest' }) returns an array whose .method matches the declared signature.
Fallback for unknown types#
Utility types you do not declare in UtilityTypeMap stay permissive and accept (...args: any[]) => any, preserving backward compatibility.