From 130c9470d902a62863221fa82ffbe9a83e4f58bc Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 29 Sep 2025 11:06:08 +0200 Subject: [PATCH 1/2] Support type arguments for generated types --- type-generation/src/astToIR.ts | 12 ++++++------ type-generation/tests/a.test.ts | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/type-generation/src/astToIR.ts b/type-generation/src/astToIR.ts index 78cd17a..9b7f637 100644 --- a/type-generation/src/astToIR.ts +++ b/type-generation/src/astToIR.ts @@ -15,6 +15,7 @@ import { SourceFile, SyntaxKind, ts, + TypeElementMemberedNode, TypeElementTypes, TypeLiteralNode, TypeNode, @@ -365,9 +366,12 @@ class SyntheticTypeConverter { } doConversion( - nodes: Pick[], + nodes: (TypeElementMemberedNode & Node)[], modifiers: Modifier, ): ReferenceTypeIR { + const res = nodes.filter((x): x is (TypeElementMemberedNode & TypeParameteredNode & Node) => Node.isTypeParametered(x)); + const typeParams = this.converter.getTypeParamsFromDecls(res); + let name = this.nameContext.join("__"); if (!name.endsWith("_iface")) { name += "_iface"; @@ -384,7 +388,7 @@ class SyntheticTypeConverter { (x) => !Node.isPropertyNamed(x) || pickSet.has(x.getName()), ); } - const result = this.converter.interfaceToIR(name, [], members, [], [], []); + const result = this.converter.interfaceToIR(name, [], members, [], [], typeParams); if (partial) { for (const prop of result.properties) { prop.isOptional = true; @@ -501,10 +505,6 @@ class SyntheticTypeConverter { } if (res.kind === "interfaces") { const { name, ifaces } = res; - const typeParams = this.converter.getTypeParamsFromDecls(ifaces); - if (typeParams.length > 0) { - throw new Error("Not handled"); - } this.nameContext.push(name); const result = this.doConversion(ifaces, modifiers); this.nameContext.pop(); diff --git a/type-generation/tests/a.test.ts b/type-generation/tests/a.test.ts index a38de89..9738463 100644 --- a/type-generation/tests/a.test.ts +++ b/type-generation/tests/a.test.ts @@ -1787,6 +1787,24 @@ describe("emit", () => { `).trim(), ); }); + it("PartialTypeArg", () => { + const res = emitFile(` + interface A { a: T; } + type D = Partial>; + declare function f(): D; + `); + assert.strictEqual( + removeTypeIgnores(res.slice(1).join("\n\n")), + dedent(` + type D = D__Partial__A_iface + + def f() -> D: ... + + class D__Partial__A_iface[T](Protocol): + a: T | None = ... + `).trim(), + ); + }) }); it("Composed type operators", () => { const res = emitFile(` From 7fb98e69a1a80b676af2b662bc0592c98167f9f9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 09:10:17 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- type-generation/src/astToIR.ts | 14 ++++++++++++-- type-generation/tests/a.test.ts | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/type-generation/src/astToIR.ts b/type-generation/src/astToIR.ts index 9b7f637..ced1193 100644 --- a/type-generation/src/astToIR.ts +++ b/type-generation/src/astToIR.ts @@ -369,7 +369,10 @@ class SyntheticTypeConverter { nodes: (TypeElementMemberedNode & Node)[], modifiers: Modifier, ): ReferenceTypeIR { - const res = nodes.filter((x): x is (TypeElementMemberedNode & TypeParameteredNode & Node) => Node.isTypeParametered(x)); + const res = nodes.filter( + (x): x is TypeElementMemberedNode & TypeParameteredNode & Node => + Node.isTypeParametered(x), + ); const typeParams = this.converter.getTypeParamsFromDecls(res); let name = this.nameContext.join("__"); @@ -388,7 +391,14 @@ class SyntheticTypeConverter { (x) => !Node.isPropertyNamed(x) || pickSet.has(x.getName()), ); } - const result = this.converter.interfaceToIR(name, [], members, [], [], typeParams); + const result = this.converter.interfaceToIR( + name, + [], + members, + [], + [], + typeParams, + ); if (partial) { for (const prop of result.properties) { prop.isOptional = true; diff --git a/type-generation/tests/a.test.ts b/type-generation/tests/a.test.ts index 9738463..d670ad0 100644 --- a/type-generation/tests/a.test.ts +++ b/type-generation/tests/a.test.ts @@ -1804,7 +1804,7 @@ describe("emit", () => { a: T | None = ... `).trim(), ); - }) + }); }); it("Composed type operators", () => { const res = emitFile(`