loving this pattern to avoid redundancy in complex class declarations...extract the props from the class prototype and use it as the constructor argument ✅ typesafe ✅ no redundant interfaces ✅ constructor becomes a one-liner
39
85
1K
Replies
the best part about this is how cleanly is extends to subclasses just add some new properties, add the new constructor type signature, and call super(props), the Object.assign in the base class constructor will set everything properly
1
0
40
oops you don't even need to mess around with prototype types...just ExtractProps<Player> works fine! https://t.co/ct7po1KDJ7
3
3
46
here's two other patterns for avoiding redundancy I'm experimented with #1 use a single property that holds all the internals (this is what Zod 3 does) #2 use interface merging like this. I haven't seen anyone do this but it's pretty nifty. but it requires two interface
1
2
12
@colinhacks Have you seen this pattern before? Incredibly useful to be able to spread props from a generic parameter onto this base type. I've used it extensively and it's super reliable- uses the same Object.assign strategy under the hood! Playground: https://t.co/G8qyoMLBm2
2
0
55
@ssalbdivad my friend you are a madman it would literally never have occured to me to try `new <t extends object>(base: t) => t`
1
0
21
@colinhacks This is fine till you’ve got properties on the class which aren’t set via the constructor. Other option is to have the class implement that interface and use it for the constructor
3
0
2
@timjreynolds when/where are these properties getting set? sounds a bit anti-patterny > have the class implement that interface this is exactly the redundancy I'm trying to avoid — I don't want the same properties declared in an interface and in the class definition
1
0
2
@_wallstreetdev Yeah with `strictPropertyInitialization: true` you're gonna need some exclamation points for required properties
1
0
1
@lxe If a property is optional in the class definition, it'll be optional in the constructor params too
1
0
0
@mathsalmi this would make all the properties optional in the constructor (both are required in this example) and still leave method signatures in the constructor param type (which you don't want...this example didn't include methods for the sake of twitter-friendliness)
1
0
1
@colinhacks Seems it does not play that well with https://t.co/LTpA0cFkMk (true by default in strict). You get a list of "Property 'id' has no initializer ... ts(2564)" the only way around is to fill the class properties with "!" - not really clean. Wish the tsc was smarter here.
1
0
0
@relucri Yeah I'd disabled that for some reason what's a few exclamations points among friends? pat yourself on the back for being smarter than the compiler! 🫠
0
0
0
@colinhacks @JacobMGEvans love this kind of Typescript patterns, tbh output keeps the same, but it’s super comfortable and simple, satisfying to implement it ✨
0
0
2