Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strongly-typed-load-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"counterfact": minor
---

Export `ContextArgs` type from generated `types/scenario-context.ts` so that `_.context.ts` files can strongly type the `loadContext` and `readJson` parameters received in the Context constructor. The default `_.context.ts` template now imports and uses `ContextArgs`.
6 changes: 6 additions & 0 deletions src/typescript-generator/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ function buildApplyContextContent(contextFiles: ContextFileInfo[]): string {
"/** A scenario function that receives the live REPL environment */",
"export type Scenario = ($: ApplyContext) => Promise<void> | void;",
"",
"/** Interface for Context objects defined in _.context.ts files */",
"export interface BaseContext {",
' readonly loadContext: ApplyContext["loadContext"];',
" readonly readJson: (relativePath: string) => Promise<unknown>;",
"}",
"",
];

return parts.join("\n");
Expand Down
12 changes: 10 additions & 2 deletions src/typescript-generator/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ export class Repository {

await fs.writeFile(
contextFilePath,
`/**
`import type { BaseContext } from "../types/scenario-context.js";

/**
* This is the default context for Counterfact.
*
* It defines the context object in the REPL
Expand All @@ -158,8 +160,14 @@ export class Repository {
*
* See https://counterfact.dev/docs/usage.html#working-with-state-the-codecontextcode-object-and-codecontexttscode
*/
export class Context {
export class Context implements BaseContext {
readonly loadContext: BaseContext["loadContext"];
readonly readJson: BaseContext["readJson"];

constructor({ loadContext, readJson }: BaseContext) {
this.loadContext = loadContext;
this.readJson = readJson;
}
}
`,
);
Expand Down
7 changes: 7 additions & 0 deletions test/typescript-generator/generate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ describe("scenario-context type generation", () => {
expect(content).toContain(
"export type Scenario = ($: ApplyContext) => Promise<void> | void;",
);
expect(content).toContain("export interface BaseContext {");
expect(content).toContain(
' readonly loadContext: ApplyContext["loadContext"];',
);
expect(content).toContain(
" readonly readJson: (relativePath: string) => Promise<unknown>;",
);
});
});

Expand Down
Loading