Incorrect type conversion for slice of nested struct alias
Closed this issue · 4 comments
When converting a slice of a nested struct alias, the type is incorrectly inferred as readonly unknown[] instead of the expected struct type.
Environments
Go version: go version go1.23.8 darwin/arm64
guts version: v1.3.0
Steps to Reproduce:
-
Add the following Go code to
testdata/alias/alias.go:package alias type FooStruct struct { Key string } type AliasStruct = FooStruct type AliasStructNested = AliasStruct type AliasStructSlice = []FooStruct type AliasStructNestedSlice = []AliasStructNested
-
Run the test for the alias generation:
go test -run "TestGeneration/alias"
Actual Behavior:
The test fails with the following diff, showing AliasStructNestedSlice is converted to readonly unknown[]:
--- Expected
+++ Actual
@@ -15,2 +15,23 @@
// From alias/alias.go
+export interface AliasStruct {
+ readonly Key: string;
+}
+
+// From alias/alias.go
+export interface AliasStructNested {
+ readonly Key: string;
+}
+
+// From alias/alias.go
+export type AliasStructNestedSlice = readonly unknown[];
+
+// From alias/alias.go
+export type AliasStructSlice = readonly FooStruct[];
+
+// From alias/alias.go
export type Foo = string;
+
+// From alias/alias.go
+export interface FooStruct {
+ readonly Key: string;
+}Specifically, the generated TypeScript for AliasStructNestedSlice is:
// From alias/alias.go
export type AliasStructNestedSlice = readonly unknown[];Expected Behavior:
The AliasStructNestedSlice should be converted to a slice of the aliased struct type.
Potential Cause and Workaround:
It seems the issue might be related to how types.Alias is handled. In the following code snippet
Lines 1006 to 1008 in ad36901
If ty.Underlying() is changed to ty.Rhs(), AliasStructNestedSlice is converted to readonly FooStruct[]. The diff for the test results with this change is:
--- Expected
+++ Actual
@@ -15,2 +15,23 @@
// From alias/alias.go
+export interface AliasStruct {
+ readonly Key: string;
+}
+
+// From alias/alias.go
+export interface AliasStructNested {
+ readonly Key: string;
+}
+
+// From alias/alias.go
+export type AliasStructNestedSlice = readonly FooStruct[];
+
+// From alias/alias.go
+export type AliasStructSlice = readonly FooStruct[];
+
+// From alias/alias.go
export type Foo = string;
+
+// From alias/alias.go
+export interface FooStruct {
+ readonly Key: string;
+}While changing ty.Underlying() to ty.Rhs() resolves the immediate issue of unknown[], I'm unsure whether AliasStructNestedSlice should be converted to readonly AliasStructNested[] or readonly FooStruct[]. Further discussion on the desired behavior for nested aliases would be beneficial.
I will take a look! .Rhs() was added somewhat recently.
That is a good question on the nested aliases. I could see the un-nesting of aliases being a post processing step that could be an opt in. 🤔
I'm going to let it traverse the alias all the way.
We could debate AliasStructNested[] vs FooStruct[]. At present I've been traversing the alias all the way, so I will continue that pattern for now.
Thank you for addressing this issue so promptly! I really appreciate it.
Thanks for raising the issue 👍