@@ -40,13 +40,15 @@ export interface Any {
4040
4141export const any = ( ) : Any => ( { type : 'Any' } ) ;
4242
43+ type ApplyLike = Extract < Expr , { type : 'Apply' | 'LiftedTerminal' | 'Param' } > ;
44+
4345export interface Apply {
4446 type : 'Apply' ;
4547 ruleName : string ;
46- children : ( Apply | Param ) [ ] ;
48+ children : ApplyLike [ ] ;
4749}
4850
49- export const apply = ( ruleName : string , children : ( Apply | Param ) [ ] = [ ] ) : Apply => ( {
51+ export const apply = ( ruleName : string , children : ApplyLike [ ] = [ ] ) : Apply => ( {
5052 type : 'Apply' ,
5153 ruleName,
5254 children
@@ -217,12 +219,16 @@ function checkNotNull<T>(x: T, msg = 'unexpected null value'): NonNullable<T> {
217219 return x ;
218220}
219221
220- function checkExprType < T extends ExprType > (
222+ function checkApplyLike ( exp : Expr ) : ApplyLike {
223+ return checkExprType ( exp , 'Apply' , 'LiftedTerminal' , 'Param' ) ;
224+ }
225+
226+ function checkExprType < T extends Expr [ 'type' ] > (
221227 exp : Expr ,
222- expectedType : T
228+ ... types : T [ ]
223229) : Extract < Expr , { type : T } > {
224- if ( exp . type !== expectedType ) {
225- throw new Error ( `Expected expression of type ' ${ expectedType } ' , but got '${ exp . type } '` ) ;
230+ if ( ! types . includes ( exp . type as T ) ) {
231+ throw new Error ( `Expected one of [ ${ types . join ( ', ' ) } ] , but got '${ exp . type } '` ) ;
226232 }
227233 return exp as Extract < Expr , { type : T } > ;
228234}
@@ -261,7 +267,7 @@ export function collectParams(exp: Expr, seen = new Set<number>()): Param[] {
261267 }
262268}
263269
264- // TODO: Maybe make the types tighter here, to avoid the use checkExprType .
270+ // TODO: Maybe make the types tighter here, to avoid the use checkApplyLike .
265271export function substituteParams < T extends Expr > (
266272 exp : T ,
267273 actuals : Exclude < Expr , Param > [ ]
@@ -273,9 +279,9 @@ export function substituteParams<T extends Expr>(
273279 if ( exp . children . length === 0 ) return exp ;
274280 return apply (
275281 exp . ruleName ,
276- exp . children . map ( ( c ) : Apply => {
282+ exp . children . map ( ( c ) : ApplyLike => {
277283 const ans = substituteParams ( c , actuals ) ;
278- return checkExprType ( ans , 'Apply' ) ;
284+ return checkApplyLike ( ans ) ;
279285 } )
280286 ) ;
281287 case 'Dispatch' : {
0 commit comments