Skip to content

Commit a723e32

Browse files
committed
feat: Express embedded structs via extends in TypeScript
1 parent f0be885 commit a723e32

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

scripts/apitypings/main.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,28 @@ func (g *Generator) posLine(obj types.Object) string {
237237
func (g *Generator) buildStruct(obj types.Object, st *types.Struct) (string, error) {
238238
var s strings.Builder
239239
_, _ = s.WriteString(g.posLine(obj))
240+
_, _ = s.WriteString(fmt.Sprintf("export interface %s ", obj.Name()))
240241

241-
_, _ = s.WriteString(fmt.Sprintf("export interface %s {\n", obj.Name()))
242+
// Handle named embedded structs in the codersdk package via extension.
243+
var extends []string
244+
extendedFields := make(map[int]bool)
245+
for i := 0; i < st.NumFields(); i++ {
246+
field := st.Field(i)
247+
if field.Embedded() && field.Pkg().Name() == "codersdk" {
248+
extendedFields[i] = true
249+
extends = append(extends, field.Name())
250+
}
251+
}
252+
if len(extends) > 0 {
253+
_, _ = s.WriteString(fmt.Sprintf("extends %s ", strings.Join(extends, ", ")))
254+
}
255+
256+
_, _ = s.WriteString("{\n")
242257
// For each field in the struct, we print 1 line of the typescript interface
243258
for i := 0; i < st.NumFields(); i++ {
259+
if extendedFields[i] {
260+
continue
261+
}
244262
field := st.Field(i)
245263
tag := reflect.StructTag(st.Tag(i))
246264

@@ -326,7 +344,7 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
326344
return TypescriptType{
327345
ValueType: "any",
328346
AboveTypeLine: fmt.Sprintf("%s\n%s",
329-
indentedComment("Embedded struct, please fix by naming it"),
347+
indentedComment("Embedded anonymous struct, please fix by naming it"),
330348
indentedComment("eslint-disable-next-line @typescript-eslint/no-explicit-any"),
331349
),
332350
}, nil

0 commit comments

Comments
 (0)