@@ -861,7 +861,30 @@ const rule: TSESLint.RuleModule<MessageIds, []> = {
861861 } else if ( node . type === "JSXSpreadAttribute" ) {
862862 // allow <div {...props.nestedProps} />; {...props} is already ignored
863863 pushTrackedScope ( node . argument , "expression" ) ;
864- } else if ( node . type === "CallExpression" || node . type === "NewExpression" ) {
864+ } else if ( node . type === "NewExpression" ) {
865+ const {
866+ callee,
867+ arguments : { 0 : arg0 } ,
868+ } = node ;
869+ if (
870+ callee . type === "Identifier" &&
871+ arg0 &&
872+ // Observers from Standard Web APIs
873+ [
874+ "IntersectionObserver" ,
875+ "MutationObserver" ,
876+ "PerformanceObserver" ,
877+ "ReportingObserver" ,
878+ "ResizeObserver" ,
879+ ] . includes ( callee . name )
880+ ) {
881+ // Observers callbacks are NOT tracked scopes. However, they
882+ // don't need to react to updates to reactive variables; it's okay
883+ // to poll the current value. Consider them called-function tracked
884+ // scopes for our purposes.
885+ pushTrackedScope ( arg0 , "called-function" ) ;
886+ }
887+ } else if ( node . type === "CallExpression" ) {
865888 if ( node . callee . type === "Identifier" ) {
866889 const {
867890 callee,
@@ -897,15 +920,9 @@ const rule: TSESLint.RuleModule<MessageIds, []> = {
897920 "setImmediate" ,
898921 "requestAnimationFrame" ,
899922 "requestIdleCallback" ,
900- // Observers from Standard Web APIs
901- "IntersectionObserver" ,
902- "MutationObserver" ,
903- "PerformanceObserver" ,
904- "ReportingObserver" ,
905- "ResizeObserver" ,
906923 ] . includes ( callee . name )
907924 ) {
908- // on*, timers, and observers are NOT tracked scopes. However, they
925+ // on* and timers are NOT tracked scopes. However, they
909926 // don't need to react to updates to reactive variables; it's okay
910927 // to poll the current value. Consider them called-function tracked
911928 // scopes for our purposes.
0 commit comments