nitro icon indicating copy to clipboard operation
nitro copied to clipboard

fix: optional variant fields dont use typescript name in generated files

Open szymonograbek opened this issue 2 months ago • 7 comments

Fixes #921

I've done some debugging on this issue and I've found out the following:

When an optional property or parameter uses a type alias for a variant, getTypeAtLocation() expands it to include | undefined, which creates a new anonymous union that loses the original alias name. This caused generated files to use names like Variant_String_Car instead of NamedVariant.

The fix uses getTypeNode().getType() to read the type from the syntax tree to preserve the alias name.

As a note, I'm not an expert on ts-morph or typescript's AST, so I don't know if this is the proper way to fix the original issue.

szymonograbek avatar Oct 09 '25 07:10 szymonograbek

@szymonograbek is attempting to deploy a commit to the Margelo Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Oct 09 '25 07:10 vercel[bot]

Hey thanks for your PR, this is great!

I also really appreciate that you added a test case for this - two change requests I have before I can merge this:

  1. Do you think we could simplify the logic in nitrogen to avoid having multiple different paths? Maybe we want to focus on only your path, and throw if the path cannot be hit (e.g. if getTypeNode() is undefined, which I guess should never be the case? Or maybe there's a different way that doesn't contain undefined that works in all situations...)
  2. Could you add the two test functions to getTests(...) (getTests.ts) in the example too? Otherwise I can do that later.

mrousavy avatar Oct 09 '25 14:10 mrousavy

@mrousavy done I've only left the path I've added (getTypeNode()) - I've added some guards for safety and to not have typescript errors, although we shouldn't ever run into them. The only way I found to trigger the error is to use getter/setter in the interface:

interface Test {
  get foo(): string
  set foo(value: string)
}

szymonograbek avatar Oct 10 '25 09:10 szymonograbek

Ah, I've found one issue tho, if in the TestObject.nitro.ts we change the property declaration to method signature in JsStyleStruct it throws the error:

interface JsStyleStruct {
  value: number
  onChanged(num: number): void
}

This again requires me to add a new path to the getInterfaceProperties to check if the property is a MethodSignature as getTypeNode doesn't exist on MethodSignature

EDIT: I've re-added the check for syntax kind

szymonograbek avatar Oct 10 '25 10:10 szymonograbek

structs cannot have Method signature properties. That's intentional, and should throw an error. Only function properties

mrousavy avatar Oct 10 '25 19:10 mrousavy

structs cannot have Method signature properties. That's intentional, and should throw an error. Only function properties

Ok, I've restored the simplified approach

szymonograbek avatar Oct 12 '25 09:10 szymonograbek

Looks like I've left a trailing white space so that made linting fail, I've removed it

szymonograbek avatar Oct 13 '25 10:10 szymonograbek