betterer icon indicating copy to clipboard operation
betterer copied to clipboard

Feature request: stronger typing for `.betterer.ts` exports

Open thislooksfun opened this issue 1 year ago • 2 comments

I just found this project and it sounds awesome, but one feature that is missing for me is a strongly-typed .betterer.ts file. It would be awesome if you could expose the BettererTestMap type somehow. Either directly and we can use it to enforce the export structure, or via something like a typed identity bettererConfig function (name not final). For example see how vite does strongly typed config.

Basically what I'm proposing is adding:

export type BettererConfig = BettererTestMap;
// AND / OR
export type { BettererTestMap };
// AND / OR
export function bettererConfig(tests: BettererTestMap): BettererTestMap {
  return tests;
}

That way we could write our .betterer.ts files as:

export default bettererConfig({
  'test name': () => someTest(),
});

// OR

export default {
  'test name': () => someTest(),
} satisfies BettererConfig;

// OR (for js)

/** @type {import('@betterer/betterer').BettererConfig} */
export default {
  'test name': () => someTest(),
};

thislooksfun avatar Oct 02 '24 20:10 thislooksfun

Nice, yeah certainly not opposed to this at all, only challenge might be naming collisions so it might have to be BettererTestsConfig? Happy to expose that for V6.

I don't personally see a huge benefit in a bettererConfig function, even though I like the pattern a lot in vite/st - I guess it would be useful if you wanted to declare CLI flags inline with your tests but I've kind of kept them separate intentionally.

Also thinking more generally, I'd like to move away from having multiple tests declared in one place. Right now, the file is executed once on the main thread to get all the info, and then again on a worker thread, which is pretty unexpected. I think it would be nicer to have something more like .*.spec.ts files:

// test-name.betterer.ts (or something)

export const name = 'test name'; // optional pretty name 

export default () => someTest();

Maybe that removes the need for this all together? Probably more like a V7 thing though 😎

phenomnomnominal avatar Oct 03 '24 22:10 phenomnomnominal

Nice, yeah certainly not opposed to this at all, only challenge might be naming collisions so it might have to be BettererTestsConfig? Happy to expose that for V6.

I don't really care what the name is as long as it's exposed!

I don't personally see a huge benefit in a bettererConfig function, even though I like the pattern a lot in vite/st - I guess it would be useful if you wanted to declare CLI flags inline with your tests but I've kind of kept them separate intentionally.

I mainly just think it looks nicer and is likely more beginner-friendly. Everyone knows how functions work, not everyone understands TS satisfies syntax. Plus it would avoid needing to do an @type JSDoc comment to get autocomplete in js files. It doesn't even need to do anything, just exporting this would be enough:

export function bettererConfig(tests: BettererTestMap): BettererTestMap {
  return tests;
}

Also thinking more generally, I'd like to move away from having multiple tests declared in one place. [...]

I wrote up a big response to this, but it got way off topic for this thread so I put it up in a discussion instead: #1229.

thislooksfun avatar Oct 13 '24 06:10 thislooksfun