Skip to content

Commit

Permalink
Experiment 3
Browse files Browse the repository at this point in the history
  • Loading branch information
soenkehahn committed Nov 13, 2023
1 parent c0d20e0 commit fa8aa1b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 20 deletions.
10 changes: 7 additions & 3 deletions ts/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ describe("Project.add", () => {
});

it("provides a nice type synonym for plugins that add a field", () => {
const plugin: Plugin<{}, { addedField: garn.Package }> = (p) => ({
const plugin: Plugin<object, { addedField: garn.Package }> = (p) => ({
...p,
addedField: garn.build``,
});
Expand All @@ -153,7 +153,9 @@ describe("Project.add", () => {
});

it("provides a nice type synonym for plugins that add multiple fields", () => {
const plugin: Plugin<{}, { one: garn.Package; two: garn.Check }> = (p) => ({
const plugin: Plugin<object, { one: garn.Package; two: garn.Check }> = (
p,
) => ({
...p,
one: garn.build``,
two: garn.check(""),
Expand Down Expand Up @@ -186,10 +188,12 @@ describe("Project.add", () => {
.add(plugin);
assertTypeIsExecutable(project.foo);
assertTypeIsExecutable(project.addedField);
// @ts-expect-error - `dep` is missing
() => garn.mkProject({ description: "" }, {}).add(plugin);
});

it("allows to overwrite fields", () => {
const plugin: Plugin<{}, { field: Package }> = (p) => ({
const plugin: Plugin<object, { field: Package }> = (p) => ({
...p,
field: garn.build``,
});
Expand Down
31 changes: 14 additions & 17 deletions ts/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ export type ProjectData = {
defaultExecutable?: Executable;
};

export type Plugin<Dependencies, Additions> = (
project: Dependencies
) => Additions;
export type Plugin<Input, Output> = (project: Input) => Output;

type ProjectHelpers = {
/**
Expand Down Expand Up @@ -82,10 +80,10 @@ type ProjectHelpers = {
* .add(self => self.addExecutable("codegen")`${self.mainPackage}/bin/codegen`)
* ```
*/
add<T extends Project, Additions>(
this: T,
fn: T extends infer Dependencies ? Plugin<Dependencies, Additions> : never,
): Omit<T, keyof Additions> & Additions;
add<Input extends ProjectData, Output>(
this: Input,
fn: Plugin<Input, Output>,
): Omit<Input, keyof Output> & Output;

/**
* Adds an `Executable` with the given name to the Project
Expand Down Expand Up @@ -219,14 +217,11 @@ const proxyEnvironmentHelpers = (): ProjectHelpers => ({
return mkShellPackage(defaultEnvironment, s, ...args);
},

add<T extends Project, Additions>(
this: T,
fn: T extends infer Dependencies ? Plugin<Dependencies, Additions> : never,
): Omit<T, keyof Additions> & Additions {
return {
...this,
...fn(this),
};
add<Input extends ProjectData, Output>(
this: Input,
fn: Plugin<Input, Output>,
): Omit<Input, keyof Output> & Output {
return { ...this, ...fn(this) };
},

addExecutable<T extends ProjectData, Name extends string>(
Expand Down Expand Up @@ -259,7 +254,8 @@ const proxyEnvironmentHelpers = (): ProjectHelpers => ({
[
`${exportName} exports the return type of "addExecutable", but this is not the proper usage of addExecutable.`,
'Did you forget the template literal? Example usage: project.addExecutable("executable-name")`shell script to run`',
].join(" "));
].join(" "),
);
return templateLiteralFn;
},

Expand Down Expand Up @@ -293,7 +289,8 @@ const proxyEnvironmentHelpers = (): ProjectHelpers => ({
[
`${exportName} exports the return type of "addCheck", but this is not the proper usage of addCheck.`,
'Did you forget the template literal? Example usage: project.addCheck("check-name")`shell script to run`',
].join(" "));
].join(" "),
);
return templateLiteralFn;
},

Expand Down

0 comments on commit fa8aa1b

Please sign in to comment.