is there any way to create a component that takes parameters? eg.
@Component({ tag: '...' })export class example extends BaseComponent { constructor(...args[]: unknown[])}
@Component({ tag: '...' })export class example extends BaseComponent { constructor(...args[]: unknown[])}
the component is only ever constructed by calling
components.addComponent()
components.addComponent()
Solution
Late but there is a simple way to do it with a macro:
/** @metadata macro */export function makeComponent<T>(attributes?: { [key: string]: AttributeValue }, instance?: Instance, id?: Modding.Generic<T, 'id'>) { const components = Dependency<Components>(); if (!instance) { instance = new Instance('Part', Workspace); } for (const [idx, v] of pairs(attributes || {})) { instance.SetAttribute(idx as string, v); } return components.addComponent(instance, id);}
/** @metadata macro */export function makeComponent<T>(attributes?: { [key: string]: AttributeValue }, instance?: Instance, id?: Modding.Generic<T, 'id'>) { const components = Dependency<Components>(); if (!instance) { instance = new Instance('Part', Workspace); } for (const [idx, v] of pairs(attributes || {})) { instance.SetAttribute(idx as string, v); } return components.addComponent(instance, id);}
This just takes the component you want to create, whatever attributes you want to attach to it (which should align with the ones it requires) and optionally an instance to attach it to and uses the macro api to get the ID of the component you passed. You could probably also use the passed component to assert required attributes or get intellisense for them but I am too lazy. This is better than explicitly passing parameters to components since the component will not get those parameters if it's just constructed by a preexisting tagged object, and having multiple ways a component can get constructed is confusing. Hopefully this helps anyone searching for an answer