-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
createLanguageThis is advertised as inference-friendly (so callers can avoid writing explicit language types), but on Deno 2.6.8 (TypeScript 5.9.2) the inferred types for productions referenced via this often collapse to Parser<unknown>. This causes downstream combinators like either(...) / seq(...) to yield unknown values and breaks type-checking.
Versions
- Deno: 2.6.8
- TypeScript: 5.9.2 (via Deno)
- combine: jsr:@claudiu-ceia/combine@0.2.6
Repro
Save as repro.ts:
import {
createLanguageThis,
either,
map,
number,
regex,
seq,
} from "jsr:@claudiu-ceia/combine@0.2.6";
export const Lang = createLanguageThis({
Literal() {
return map(regex(/k/i, "k"), () => 1000);
},
ShortLiteral() {
return map(regex(/m/i, "m"), () => 1_000_000);
},
Inner() {
return map(
seq(number(), either(this.Literal, this.ShortLiteral)),
([num, lit]) => num * lit,
);
},
parser() {
return this.Inner;
},
});Run:
deno check repro.tsActual
Type error:
TS18046 [ERROR]: 'lit' is of type 'unknown'.
Expected
lit should be inferred as number (since both Literal() and ShortLiteral() return Parser<number>).
Workaround
Provide an explicit defs type via the generic parameter:
import type { Parser } from "jsr:@claudiu-ceia/combine@0.2.6";
type L = {
Literal: () => Parser<number>;
ShortLiteral: () => Parser<number>;
Inner: () => Parser<number>;
parser: () => Parser<number>;
};
export const Lang2 = createLanguageThis<L>({ /* same body */ });Notes
This seems to be tied to how createLanguageThis’s signature infers T and then computes BoundFromThisDefs<T> (in src/language.ts). Inference appears to lose the specific return type for methods when those methods are used through this inside other methods.