@@ -45,6 +45,9 @@ import type {
4545 Identifier ,
4646 Operator ,
4747 PreludeOperator ,
48+ ContainerQuery ,
49+ FeatureRange ,
50+ String ,
4851} from './node-types'
4952
5053// ---------------------------------------------------------------------------
@@ -328,6 +331,52 @@ describe('type narrowing — compile-time', () => {
328331 }
329332 } )
330333
334+ test ( 'FeatureRange children are typed as Dimension | PreludeOperator, not Operator' , ( ) => {
335+ const atrule = parse ( '@media (width >= 400px) {}' ) . first_child ! as Atrule
336+ const range = atrule . prelude ! . first_child ! . first_child ! as FeatureRange
337+ expectTypeOf ( range . children ) . toEqualTypeOf < ( Dimension | PreludeOperator ) [ ] > ( )
338+
339+ const [ op , dim ] = range . children
340+ expect ( op . type_name ) . toBe ( 'Operator' )
341+ expect ( dim . type_name ) . toBe ( 'Dimension' )
342+ } )
343+
344+ test ( 'ContainerQuery children include PreludeOperator for and/or/not, without casting' , ( ) => {
345+ const atrule = parse ( '@container style(a: 1) and style(b: 2) {}' ) . first_child ! as Atrule
346+ const containerQuery = atrule . prelude ! . first_child ! as ContainerQuery
347+ expectTypeOf ( containerQuery . children ) . toEqualTypeOf <
348+ ( Identifier | MediaFeature | Function | PreludeOperator ) [ ]
349+ > ( )
350+
351+ const [ , op ] = containerQuery . children
352+ expect ( op . type_name ) . toBe ( 'Operator' )
353+ expect ( ( op as PreludeOperator ) . text ) . toBe ( 'and' )
354+ } )
355+
356+ test ( 'AtrulePrelude children include Identifier for @keyframes/@page/@property preludes' , ( ) => {
357+ const atrule = parse ( '@keyframes spin {}' ) . first_child ! as Atrule
358+ const prelude = atrule . prelude ! as AtrulePrelude
359+ const [ ident ] = prelude . children
360+
361+ expect ( ident . type_name ) . toBe ( 'Identifier' )
362+ if ( ident . type_name === 'Identifier' ) {
363+ expectTypeOf ( ident ) . toExtend < Identifier > ( )
364+ expect ( ident . text ) . toBe ( 'spin' )
365+ }
366+ } )
367+
368+ test ( 'AtrulePrelude children include String for @charset' , ( ) => {
369+ const root = parse ( '@charset "UTF-8";' )
370+ const atrule = root . first_child ! as Atrule
371+ const prelude = atrule . prelude ! as AtrulePrelude
372+ const [ str ] = prelude . children
373+
374+ expect ( str . type_name ) . toBe ( 'String' )
375+ if ( str . type_name === 'String' ) {
376+ expectTypeOf ( str ) . toExtend < String > ( )
377+ }
378+ } )
379+
331380 test ( 'AnyCss enables switch narrowing' , ( ) => {
332381 // This test verifies the discriminated union works for switch narrowing.
333382 // The function must compile without type errors.
0 commit comments