-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use nesting to represent nesting #44
Comments
Yeah, I fought with this pretty hard. In TS you can't nest types, unfortunately. You can nest objects, but the result isn't as nice as you'd hope: class B {
constructor() { ... }
}
class A {
static readonly B = B;
}
// This is fine.
const x = new B();
// Also fine.
const y = new A.B();
// Compiler error. :(
let z: A.B; After thinking about it a lot, I realized it's best not to even nest the structs at all since I figured people were going to hit that wall pretty quick and be confused why that last line won't compile. Maybe this is a thing to bring up to the TypeScript team? Possibly an existing issue already? At the very least this caveat should be documented loudly. |
Still scratching my head over why that last line would be an error. Pity, as it seems quite natural. |
Does this have the same issues you described? https://stackoverflow.com/a/32494175 |
Yep that's basically the same problem. It's extra gnarly when you need to export the class with the nested type. I think I made an attempt to solve it using namespaces and gave up. If you're feeling adventurous, try editing schema.capnp.ts manually and see if you can get it to compile with an exported namespace and nested types! |
I never got my head around TS namespaces. I've mainly only had bad experiences with them. In this case anyway, can a namespace double as a class? Because the outer name still needs to be the outer type. Regardless, sounds like you've done a lot of exploration but I might have a play around with this anyway. |
This does look promising:
But maybe you already tried this and know how it might fail? Note I went with I'm not gonna try and adapt the schema / code generator to do this yet as I want to get current work on capnpc-js squared away but I'm happy to come back to this. |
I think I remember trying that, and I believe you run into use-before-declare issues with self-referencing types. Notwithstanding the fact that writing the codegen for that is going to be a doozy. It's worth trying again, though. |
Namespaces may work without a major headache. They even get around some of the use before define issues I run into elsewhere. export class Foo {
static foo = 'foo';
bar: Foo.Bar;
constructor() {
this.bar = new Foo.Bar();
}
}
export namespace Foo {
export class Bar {
static bar = 'bar';
}
export class Fotz extends Foo.Bar { }
}
let x: Foo.Bar = new Foo.Bar(); I'm weary of the past horrors with namespaces but am willing to take the dive; the compiled schemas are pretty lacking without proper nested types. |
This needs further exploration now that TypeScript has advanced a bit. The codegen will still be tough. |
I noticed that in our codegen we transform nested things into top-level members with an underscore between parent and nested member. eg.
CodeGeneratorRequest_RequestedFile
Whereas (for example) in the official capnproto C++ compiler they generate an actually nestedRequestedFile
struct inside theCodeGeneratorRequest
struct.See:
https://github.com/jdiaz5513/capnp-ts/blob/master/packages/capnp-ts/src/std/schema.capnp.ts#L989
Vs:
https://github.com/capnproto/capnproto/blob/1dcabbf81d772069119773025d44c29df19ccd30/c%2B%2B/src/capnp/schema.capnp.h#L626
I think it would be more intuitive to match the C++ style and nest emitted things when they're nested in the schema, if there's no barrier to doing so in TS that I'm unaware of.
The text was updated successfully, but these errors were encountered: