R
roblox-ts•2mo ago
kv_

component constructor parameters

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()
Solution:
Late but there is a simple way to do it with a macro: ```ts /** @metadata macro */ export function makeComponent<T>(attributes?: { [key: string]: AttributeValue }, instance?: Instance, id?: Modding.Generic<T, 'id'>) { const components = Dependency<Components>();...
Jump to solution
9 Replies
Tester
Tester•2mo ago
you mean normal typescript decorator or flamework one?
kv_
kv_OP•2mo ago
flamework
Tesmi
Tesmi•2mo ago
create your own Startup method that you will call yourself
Unknown User
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
kv_
kv_OP•2mo ago
it probably is, but who cares😋 since these parameters would not be passed to components not created in this manner
Solution
kv_
kv_•2mo ago
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
kv_
kv_OP•2mo ago
Some horrible thing like this:
export function makeComponent<
T extends BaseComponent<{}, Instance>, // we found type hell
A extends T extends BaseComponent<infer U, Instance> ? U : never = T extends BaseComponent<infer U, Instance> ? U : never,
I extends T extends BaseComponent<{}, infer U> ? U : never = T extends BaseComponent<{}, infer U> ? U : never,
>(attributes: A, instance: I, id?: Modding.Generic<T, 'id'>) {
const components = Dependency<Components>();

for (const [idx, v] of pairs(attributes || {})) {
instance.SetAttribute(idx as string, v as AttributeValue);
}

return components.addComponent(instance, id);
}
export function makeComponent<
T extends BaseComponent<{}, Instance>, // we found type hell
A extends T extends BaseComponent<infer U, Instance> ? U : never = T extends BaseComponent<infer U, Instance> ? U : never,
I extends T extends BaseComponent<{}, infer U> ? U : never = T extends BaseComponent<{}, infer U> ? U : never,
>(attributes: A, instance: I, id?: Modding.Generic<T, 'id'>) {
const components = Dependency<Components>();

for (const [idx, v] of pairs(attributes || {})) {
instance.SetAttribute(idx as string, v as AttributeValue);
}

return components.addComponent(instance, id);
}
Unknown User
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
kv_
kv_OP•2mo ago
For my purposes the component either is never removed or is removed by destroying it's instance, alternatively, I also have a remove component macro

Did you find this page helpful?