Typesafe Struct Constructors
ian-harshman-ck opened this issue · comments
This is something that stems from the original Apache implementation, but I think it could be improved upon.
In the generated code, thrift structs are currently populated via the read
instance method:
const struct = new MyStruct()
struct.read(inputProtocol)
This means that the MyStruct's constructor arg has to be optional, otherwise we wouldn't be able to call the empty constructor. Unfortunately this makes constructors less type-safe for consumers. Even if MyStruct has a bunch of required fields...
struct MyStruct {
1: required i32 field1
2: required string field2
...
... the constructor can still be called with no arguments because the generated code requires it.
const struct = new MyStruct() // compiles, but should require fields
Alternative Approach
The read
methods can be static. Something like
const struct = MyStruct.read(input)
This would free up the constructor signature to require a valid set of input arguments, which would result in required fields being type-checked (If a struct has no fields, we could make an exception in that case).
class MyStruct {
constructor(args: IMyStructArgs) {...} // constructor args are no longer optional
}
I've POC'd this by manually editing generated code and it seems to work just fine, though I haven't looked at memory / time complexity.
Anyway, not a high priority, just some food for thought.
Good call. I like it.
There is one complication to this. It breaks interface compatibility with the apache library. I had added an interface to the @types that all struct-like objects implement (structs, unions, exceptions). The only place this is being used now is in the thrift-utils project, but our generated code would need to drop this to implement this. May not be a big deal. Definitely the approach we should take as we build out server-core.
Resolved by #95