Repository: alloy-framework/alloy
Pull request #212 (2025-06-23 17:53:07)

Add support for class base type(s)
Following the names in the `ClassDeclaration` of the roslyn csharp generator


Patch:
diff --git a/.chronus/changes/class-base-2025-5-23-17-53-25.md b/.chronus/changes/class-base-2025-5-23-17-53-25.md
new file mode 100644
index 0000000..abde056
--- /dev/null
+++ b/.chronus/changes/class-base-2025-5-23-17-53-25.md
@@ -0,0 +1,8 @@
+---
+# Change versionKind to one of: breaking, feature, fix, internal
+changeKind: feature
+packages:
+  - "@alloy-js/csharp"
+---
+
+Add support for class base type(s)
diff --git a/packages/csharp/src/components/ClassDeclaration.tsx b/packages/csharp/src/components/ClassDeclaration.tsx
index c1a2e03..5eba44e 100644
--- a/packages/csharp/src/components/ClassDeclaration.tsx
+++ b/packages/csharp/src/components/ClassDeclaration.tsx
@@ -1,4 +1,5 @@
 import * as core from "@alloy-js/core";
+import { join } from "@alloy-js/core";
 import {
   AccessModifiers,
   computeModifiersPrefix,
@@ -36,6 +37,12 @@ export interface ClassDeclarationProps
   doc?: core.Children;
   refkey?: core.Refkey;
   typeParameters?: Record<string, core.Refkey>;
+
+  /** Base class that this class extends */
+  baseType?: core.Children;
+
+  /** Interfaces this class implements */
+  interfaceTypes?: core.Children[];
 }
 
 /**
@@ -102,6 +109,12 @@ export function ClassDeclaration(props: ClassDeclarationProps) {
     );
   }
 
+  const bases = [
+    ...(props.baseType ? [props.baseType] : []),
+    ...(props.interfaceTypes || []),
+  ];
+  const base =
+    bases.length > 0 ? <> : {join(bases, { joiner: ", " })}</> : null;
   const modifiers = computeModifiersPrefix([
     getAccessModifier(props),
     getClassModifiers(props),
@@ -111,6 +124,7 @@ export function ClassDeclaration(props: ClassDeclarationProps) {
       <DocWhen doc={props.doc} />
       {modifiers}class <Name />
       {typeParams}
+      {base}
       {!props.children && ";"}
       {props.children && (
         <core.Block newline>


Test patch:
diff --git a/packages/csharp/test/class-declaration.test.tsx b/packages/csharp/test/class-declaration.test.tsx
index 932085b..8a2bfa6 100644
--- a/packages/csharp/test/class-declaration.test.tsx
+++ b/packages/csharp/test/class-declaration.test.tsx
@@ -47,6 +47,45 @@ describe("modifiers", () => {
   });
 });
 
+describe("base", () => {
+  it("define base class", () => {
+    expect(
+      <utils.TestNamespace>
+        <csharp.ClassDeclaration name="TestClass" baseType="Foo" />
+      </utils.TestNamespace>,
+    ).toRenderTo(`
+        class TestClass : Foo;
+    `);
+  });
+
+  it("define multiple interface types", () => {
+    expect(
+      <utils.TestNamespace>
+        <csharp.ClassDeclaration
+          name="TestClass"
+          interfaceTypes={["Foo", "Bar"]}
+        />
+      </utils.TestNamespace>,
+    ).toRenderTo(`
+        class TestClass : Foo, Bar;
+    `);
+  });
+
+  it("define base class and multiple interface types", () => {
+    expect(
+      <utils.TestNamespace>
+        <csharp.ClassDeclaration
+          name="TestClass"
+          baseType="BaseClass"
+          interfaceTypes={["Foo", "Bar"]}
+        />
+      </utils.TestNamespace>,
+    ).toRenderTo(`
+        class TestClass : BaseClass, Foo, Bar;
+    `);
+  });
+});
+
 it("declares class with some members", () => {
   const res = utils.toSourceText(
     <csharp.ClassDeclaration public name="TestClass">