#Generic components, implementation feedback

27 messages · Page 1 of 1 (latest)

main bramble
#

Hi everyone, I've been focusing on different projects for a few months and I'm surprised at how rusty I've become with TypeScript over this time (not that I ever were particularly good at it). I would like some feedback on the following code just to see if there's perhaps a better way to do it, or if I'm missing something obvious that will come and bit me later on.

Basically it's a component class that gets instantiated via a factory function that accepts a component of type T, as well as some arguments that should match the signature for that particular type. And the component type must be one of the ones that I define earlier. I've manged to put something together that seems to work, but I'm wondering if this is the right approach. I guess is better explained with some code so here's a link to the playground, thank you!

(Removed link see next message below)

burnt kayakBOT
#
joao6246#0

Preview:```ts
class Component<T> {
private readonly _id: number

constructor(id: number, args: T) {
this._id = id
Object.assign(this, args)
}

get id() {
return this._id
}
}

type TransformComponent = {
position: {x: number; y: number
...```

neon arch
#

I don't recommend doing things this way

#

this is not a good pattern in TS

#

you'll be able to set properties on a class instance, but you won't be able to access them when using the construtor to create such an object

#

because all of the specifi fields are not defined on the class

#

there is a simple mechanism to do what you're trying to do, and it's called inheritance, were you create a class that extends the base class

#

also, you Component doesn't need to be generic

#

the args parameter in the constructor can take anything, really

#

so you can very well type it as such

#

the only problem you'd need to fix is cast the instance after creating it and before returning it

#

like so

return new Component(Math.random(), args) as unknown as T;
#

but that's not ideal

#

tbh you should just be using classes, that's the right way of doing it in TS

#

your way might work, but it's quite "JavaScripty", not possible for the compiler to guarantee it's safe

main bramble
#

Hey, thanks so much for taking the time. I'm currently doing it with classes and inheritance but thought it was a bit of a "waste" since the classes in this particular example, the components, don't have any logic and are basically just objects with an id.

#

With this, I was hoping to get away without having to write multiple classes which would be lengthier but I'm inclined to agree that this is not really working...

burnt kayakBOT
#
sandiford#0

Preview:```ts
class Component<T> {
private readonly _id: number
data: T

constructor(id: number, args: T) {
this._id = id
this.data = args
//Object.assign(this, args);
}

get id() {
return this._id
}
}

type TransformCompo
...```

full rock
#

Object.assign is horrible

#

but if you move to a class property of type T, then your approach is "OK"

#

That said - I would suggest avoid doing anything that makes code less clear/readable/maintainable, in the name of saving writing a few lines of code

#

With your approach, get getting the type of createComponent<TransformComponent> is pretty awkward. You can do

type TransformComponentType = ReturnType<typeof createComponent<TransformComponent>>

But, is it worth it? If another developer comes into this project its a lot more confusing than just writing the classes

main bramble
#

Yeah I don't disagree, I already have most of the code written anyway, I'm trying mostly to see if I can have Typescript reduce that somehow

full rock
#

Simplicity > Size, IMO

#

But do as you wish : )

main bramble
#

I think the same, I'm just experimenting a bit on this one

#

In any case thanks for the input 👍