The extension object to export.
// the options array is declared first so its type can be inferred
const options = [
{ identifier: "prefix", type: "string", defaultValue: ">" },
] as const;
defineExtension<InferOptions<typeof options>>({
options,
action: (input, options) => {
popclip.pasteText(options.prefix + input.text);
},
});
Specifying the CustomOptions generic type parameter, as above, extends the
checking to the options parameter of action functions and the population
function, so options.prefix is known to exist and to be a string.
InferOptions derives that type from the options array itself, which
again avoids restating it.
Exports the extension object from a module-based extension. This is a module's entry point: PopClip loads the module, and the object given here defines the extension's actions, options and behaviour.
At runtime this is simply
module.exports = extension, and the difference is entirely one of types. Because the parameter is typed, every property of the object literal written inside the call is checked and autocompleted in place, with no type annotations anywhere. Assigning tomodule.exportscarries no type information, so nothing in the object is checked unless you first declare a separate variable annotated as Extension — restating a type that is already known here. For that reason this is the recommended way to write a module extension.Note that a module's actions are invoked through their
codefunction. The action flags —title,icon,requirements,regex,before,afterand so on — work as they do in a static config, but the action-type properties such asurl,keyComboandshellScriptare static config only, and are ignored here.