dx: better type inferred when no filter is passed to mapFilter

Massimo Melina committed Feb 18, 2026 at 23:53 UTC ca4b316b8bda18b2c698ad1305ed71d7b5907fd4
2 files changed +15 -5
playwright.config.ts
+1 -1
@@ -103,7 +103,7 @@ export default defineConfig({
103 url: 'http://127.0.0.1:8081',
104 reuseExistingServer: !process.env.CI,
105 }, { // launch a second server for tests with an empty/default config
106 - command: 'rm -rf tests/work2 && node dist/src --cwd tests/work2 --debug --open_browser_at_start false',
106 + command: 'rm -rf tests/work2 && node dist/src --cwd tests/work2 --debug --port 8082 --open_browser_at_start false', // the port here is just to avoid getting the "port busy" console warning
107 reuseExistingServer: !process.env.CI,
108 }]
109 });
src/cross.ts
+14 -4
@@ -514,13 +514,23 @@ export function inCommon<T extends string | unknown[]>(a: T, b: T) {
514 return i
515 }
516
517 -export function mapFilter<T=unknown, R=T>(arr: T[], map: (x:T, idx: number) => R, filter=(x: R) => x === undefined, invert=false) {
517 +type MapFilterResult<R, F> = F extends undefined ? Exclude<R, undefined>[]
518 + : F extends (x: R) => x is (infer S extends R) ? S[]
519 + : R[]
520 +
521 +export function mapFilter<T=unknown, R=T, F extends ((x: R) => unknown) | undefined=undefined>(
522 + arr: T[],
523 + map: (x:T, idx: number) => R,
524 + filter?: F,
525 + invert=false
526 +): MapFilterResult<R, F> {
527 + const keep = filter ?? ((x: R) => x !== undefined)
528 return arr[invert ? 'reduceRight' : 'reduce']((ret, x, idx) => {
529 const y = map(x, idx)
520 - if (filter(y))
521 - ret.push(y) // push is much faster than unshift, therefore invert using reduceRight https://measurethat.net/Benchmarks/Show/29/0/array-push-vs-unshift
530 + if (keep(y))
531 + ret.push(y) // push is much faster than unshift, therefore, invert using reduceRight https://measurethat.net/Benchmarks/Show/29/0/array-push-vs-unshift
532 return ret
523 - }, [] as R[])
533 + }, [] as R[]) as MapFilterResult<R, F>
534 }
535
536 export function callable<T>(x: Functionable<T>, ...args: unknown[]) {