Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we speed up type checking by using project references "lite"? #1356

Closed
samreid opened this issue Nov 15, 2022 · 30 comments
Closed

Can we speed up type checking by using project references "lite"? #1356

samreid opened this issue Nov 15, 2022 · 30 comments
Assignees

Comments

@samreid
Copy link
Member

samreid commented Nov 15, 2022

From #1350, there are many referenced issues about type checking in #1350 (comment). We used to use very fine project references and were surprised to see that things sped up when converting to the monolithic approach. But maybe we should investigate a coarse approach, where there is one "module" for common code, and each sim has its own module. That way, when changing one sim, it won't need to type check other sims. But changing common code would still need to type check all sims.

Anyways, we should test performance for this strategy on mac and windows, for common code change and sim change.

@samreid samreid self-assigned this Nov 15, 2022
@samreid samreid changed the title Can we speed up type checking by using project references lite? Can we speed up type checking by using project references "lite"? Nov 15, 2022
@samreid
Copy link
Member Author

samreid commented Nov 18, 2022

Project references requires changing "noEmit": true to "noEmit": false. When I did that, I also changed to "emitDeclarationOnly": true,. However, now there are Found 9842 errors in 68 files. for all our mixins, like:

../../../wave-interference/js/common/view/WaveMeterProbeNode.ts:23:7 - error TS4094: Property 'nodesThatAreActiveDescendantToThisNode' of exported class expression may not be private or protected.

23 class WaveMeterProbeNode extends InteractiveHighlighting( ProbeNode ) {
         ~~~~~~~~~~~~~~~~~~

../../../wave-interference/js/common/view/WaveMeterProbeNode.ts:23:7 - error TS4094: Property 'onBoundsListenersAddedOrRemoved' of exported class expression may not be private or protected.

23 class WaveMeterProbeNode extends InteractiveHighlighting( ProbeNode ) {
         ~~~~~~~~~~~~~~~~~~

The workaround described in microsoft/TypeScript#30355 (comment) seems to work OK though, if we are happy maintaining one type per mixin.

@samreid
Copy link
Member Author

samreid commented Nov 18, 2022

In process investigation:

Subject: [PATCH] Omit a11y strings from PhET-iO instrumentation, see https://github.com/phetsims/chipper/issues/1352
---
Index: main/scenery/js/nodes/Imageable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Imageable.ts b/main/scenery/js/nodes/Imageable.ts
--- a/main/scenery/js/nodes/Imageable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Imageable.ts	(date 1668807871806)
@@ -71,7 +71,7 @@
   hitTestPixels?: boolean;
 };
 
-const Imageable = <SuperType extends Constructor>( type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Imageable = <SuperType extends Constructor>( type: SuperType ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class ImageableMixin extends type {
 
     // (scenery-internal) Internal stateful value, see setImage()
Index: main/scenery/js/nodes/Leaf.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Leaf.ts b/main/scenery/js/nodes/Leaf.ts
--- a/main/scenery/js/nodes/Leaf.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Leaf.ts	(date 1668808229779)
@@ -11,7 +11,7 @@
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import Constructor from '../../../phet-core/js/types/Constructor.js';
 
-const Leaf = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const Leaf = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
 
   return class LeafMixin extends type {
     public constructor( ...args: IntentionalAny[] ) {
Index: main/sun/js/accessibility/AccessibleValueHandler.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleValueHandler.ts b/main/sun/js/accessibility/AccessibleValueHandler.ts
--- a/main/sun/js/accessibility/AccessibleValueHandler.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleValueHandler.ts	(date 1668807766906)
@@ -199,12 +199,12 @@
 type ParentOptions = VoicingOptions & NodeOptions;
 
 export type AccessibleValueHandlerOptions = SelfOptions & VoicingOptions; // do not use ParentOptions here!
-
+type TAccessibleValueHandler = {} & Voicing;
 /**
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class AccessibleValueHandler extends Voicing( Type ) {
     private readonly _valueProperty: TProperty<number>;
     private _enabledRangeProperty: TReadOnlyProperty<Range>;
Index: main/sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleSlider.ts b/main/sun/js/accessibility/AccessibleSlider.ts
--- a/main/sun/js/accessibility/AccessibleSlider.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleSlider.ts	(date 1668807766920)
@@ -17,6 +17,7 @@
 import Constructor from '../../../phet-core/js/types/Constructor.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import optionize from '../../../phet-core/js/optionize.js';
+import ConstructorOf from '../../../phet-core/js/types/ConstructorOf.js';
 import { Node, SceneryEvent } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
 import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
@@ -35,11 +36,13 @@
 
 type AccessibleSliderOptions = SelfOptions & AccessibleValueHandlerOptions;
 
+type TAccessibleSlider = {} & Node;
+
 /**
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) {
 
     private readonly _disposeAccessibleSlider: () => void;
Index: main/scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/util/DelayedMutate.ts b/main/scenery/js/util/DelayedMutate.ts
--- a/main/scenery/js/util/DelayedMutate.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/util/DelayedMutate.ts	(date 1668808352476)
@@ -38,7 +38,7 @@
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
   // able to parse that we're using the same keys for each call of this.
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
Index: main/scenery/js/layout/constraints/FlowConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/constraints/FlowConfigurable.ts b/main/scenery/js/layout/constraints/FlowConfigurable.ts
--- a/main/scenery/js/layout/constraints/FlowConfigurable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/constraints/FlowConfigurable.ts	(date 1668807861905)
@@ -67,7 +67,7 @@
 export type ExternalFlowConfigurableOptions = WithoutNull<FlowConfigurableOptions, Exclude<keyof FlowConfigurableOptions, 'minContentWidth' | 'minContentHeight' | 'maxContentWidth' | 'maxContentHeight'>>;
 
 // (scenery-internal)
-const FlowConfigurable = memoize( <SuperType extends Constructor>( type: SuperType ) => {
+const FlowConfigurable = memoize( <SuperType extends Constructor>( type: SuperType ):any => {
   return class FlowConfigurableMixin extends MarginLayoutConfigurable( type ) {
 
     protected _orientation: Orientation = Orientation.HORIZONTAL;
Index: main/scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/Sizable.ts b/main/scenery/js/layout/Sizable.ts
--- a/main/scenery/js/layout/Sizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/Sizable.ts	(date 1668807804666)
@@ -64,7 +64,7 @@
 type ParentOptions = WidthSizableOptions & HeightSizableOptions;
 export type SizableOptions = SelfOptions & ParentOptions;
 
-const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
   const SuperExtendedType = WidthSizable( HeightSizable( type ) );
   const SizableTrait = DelayedMutate( 'Sizable', SIZABLE_SELF_OPTION_KEYS, class SizableTrait extends SuperExtendedType {
 
Index: main/scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/WidthSizable.ts b/main/scenery/js/layout/WidthSizable.ts
--- a/main/scenery/js/layout/WidthSizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/WidthSizable.ts	(date 1668807824178)
@@ -60,7 +60,7 @@
 // values yet. If you're making something WidthSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): any => {
   const WidthSizableTrait = DelayedMutate( 'WidthSizable', WIDTH_SIZABLE_OPTION_KEYS, class WidthSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation
Index: main/sound/js/sound/model/SoundModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sound/js/sound/model/SoundModel.ts b/main/sound/js/sound/model/SoundModel.ts
--- a/main/sound/js/sound/model/SoundModel.ts	(revision 1ea219b862fac6b9b03ad457d2e5f3f26de07a65)
+++ b/main/sound/js/sound/model/SoundModel.ts	(date 1668808412497)
@@ -9,6 +9,7 @@
  */
 
 import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
+import Property from '../../../../axon/js/Property.js';
 import NumberProperty from '../../../../axon/js/NumberProperty.js';
 import Bounds2 from '../../../../dot/js/Bounds2.js';
 import Range from '../../../../dot/js/Range.js';
Index: main/scenery/js/accessibility/voicing/ReadingBlock.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/ReadingBlock.ts b/main/scenery/js/accessibility/voicing/ReadingBlock.ts
--- a/main/scenery/js/accessibility/voicing/ReadingBlock.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/ReadingBlock.ts	(date 1668807781487)
@@ -77,7 +77,7 @@
   nameHint: '{{NAME}}. {{HINT}}'
 } );
 
-const ReadingBlock = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const ReadingBlock = <SuperType extends Constructor<Node>>( Type: SuperType ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   const ReadingBlockClass = DelayedMutate( 'ReadingBlock', READING_BLOCK_OPTION_KEYS, class ReadingBlockClass extends Voicing( Type ) {
 
Index: main/gravity-and-orbits/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/gravity-and-orbits/tsconfig.json b/main/gravity-and-orbits/tsconfig.json
--- a/main/gravity-and-orbits/tsconfig.json	(revision fdf0e82a3e91fc961540473c1239ef8b45245d89)
+++ b/main/gravity-and-orbits/tsconfig.json	(date 1668808538486)
@@ -1,6 +1,11 @@
 // This file was automatically generated by grunt update
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../chipper/tsconfig/all/tsconfig.json"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: main/scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/HeightSizable.ts b/main/scenery/js/layout/HeightSizable.ts
--- a/main/scenery/js/layout/HeightSizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/HeightSizable.ts	(date 1668807824171)
@@ -60,7 +60,7 @@
 // values yet. If you're making something HeightSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
   const HeightSizableTrait = DelayedMutate( 'HeightSizable', HEIGHT_SIZABLE_OPTION_KEYS, class HeightSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation
Index: main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1668807766917)
@@ -29,7 +29,11 @@
 
 export type InteractiveHighlightingOptions = SelfOptions;
 
-const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+type IH = {
+  isInteractiveHighlighting: boolean;
+} & Node;
+
+const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   // @ts-ignore
   assert && assert( !Type._mixesInteractiveHighlighting, 'InteractiveHighlighting is already added to this Type' );
Index: main/scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/Voicing.ts b/main/scenery/js/accessibility/voicing/Voicing.ts
--- a/main/scenery/js/accessibility/voicing/Voicing.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/Voicing.ts	(date 1668807766913)
@@ -105,7 +105,47 @@
                                                  ResponsePacketOptions[PropertyName];
 };
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+// type TVoicing = {
+//   voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+//
+//   initialize( ...args: IntentionalAny[] ): this;
+//   voicingSpeakFullResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakNameResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakObjectResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakHintResponse( providedOptions?: SpeakingOptions ): void;
+//   setVoicingNameResponse( response: VoicingResponse ): void;
+//   set voicingNameResponse( response: VoicingResponse );
+//   get voicingNameResponse(): ResolvedResponse;
+//   getVoicingNameResponse(): ResolvedResponse;
+//   setVoicingObjectResponse( response: VoicingResponse ): void;
+//   set voicingObjectResponse( response: VoicingResponse );
+//   get voicingObjectResponse(): ResolvedResponse;
+//   getVoicingObjectResponse(): ResolvedResponse;
+//   setVoicingContextResponse( response: VoicingResponse ): void;
+//   set voicingContextResponse( response: VoicingResponse );
+//   get voicingContextResponse(): ResolvedResponse;
+//   getVoicingContextResponse(): ResolvedResponse;
+//   setVoicingHintResponse( response: VoicingResponse ): void;
+//   set voicingHintResponse( response: VoicingResponse );
+//   get voicingHintResponse(): ResolvedResponse;
+//   getVoicingHintResponse(): ResolvedResponse;
+//   setVoicingIgnoreVoicingManagerProperties( ignoreProperties: boolean ): void;
+//   set voicingIgnoreVoicingManagerProperties( ignoreProperties: boolean );
+//   get voicingIgnoreVoicingManagerProperties(): boolean;
+//   getVoicingIgnoreVoicingManagerProperties(): boolean;
+//   setVoicingResponsePatternCollection( patterns: ResponsePatternCollection ): void;
+//   set voicingResponsePatternCollection( patterns: ResponsePatternCollection );
+//   get voicingResponsePatternCollection(): ResponsePatternCollection;
+//   getVoicingResponsePatternCollection(): ResponsePatternCollection;
+//   setVoicingUtterance( utterance: Utterance ): void;
+//   set voicingUtterance( utterance: Utterance );
+//   get voicingUtterance(): Utterance;
+//   getVoicingUtterance(): Utterance;
+// } & Node;
+
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
Index: main/sun/js/Popupable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/Popupable.ts b/main/sun/js/Popupable.ts
--- a/main/sun/js/Popupable.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/Popupable.ts	(date 1668808313700)
@@ -42,7 +42,7 @@
 };
 export type PopupableOptions = SelfOptions & PickOptional<NodeOptions, 'tandem'>;
 
-const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   return class extends type {
 
Index: main/chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/chipper/tsconfig-core.json b/main/chipper/tsconfig-core.json
--- a/main/chipper/tsconfig-core.json	(revision 2fbbf6b97bcf73b17034d4338f997b267c6b4be4)
+++ b/main/chipper/tsconfig-core.json	(date 1668808797010)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: main/scenery/js/nodes/Paintable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Paintable.ts b/main/scenery/js/nodes/Paintable.ts
--- a/main/scenery/js/nodes/Paintable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Paintable.ts	(date 1668808240603)
@@ -67,7 +67,7 @@
 
 const PAINTABLE_DRAWABLE_MARK_FLAGS = [ 'fill', 'stroke', 'lineWidth', 'lineOptions', 'cachedPaints' ];
 
-const Paintable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const Paintable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
   assert && assert( _.includes( inheritance( type ), Node ), 'Only Node subtypes should mix Paintable' );
 
   return class PaintableMixin extends type {
Index: main/sun/js/accessibility/AccessibleNumberSpinner.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleNumberSpinner.ts b/main/sun/js/accessibility/AccessibleNumberSpinner.ts
--- a/main/sun/js/accessibility/AccessibleNumberSpinner.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleNumberSpinner.ts	(date 1668808293295)
@@ -46,7 +46,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   return class AccessibleNumberSpinner extends AccessibleValueHandler( Type, optionsArgPosition ) {
 

@samreid
Copy link
Member Author

samreid commented Nov 18, 2022

More progress:

Subject: [PATCH] Omit a11y strings from PhET-iO instrumentation, see https://github.com/phetsims/chipper/issues/1352
---
Index: main/scenery/js/nodes/Imageable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Imageable.ts b/main/scenery/js/nodes/Imageable.ts
--- a/main/scenery/js/nodes/Imageable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Imageable.ts	(date 1668807871806)
@@ -71,7 +71,7 @@
   hitTestPixels?: boolean;
 };
 
-const Imageable = <SuperType extends Constructor>( type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Imageable = <SuperType extends Constructor>( type: SuperType ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class ImageableMixin extends type {
 
     // (scenery-internal) Internal stateful value, see setImage()
Index: main/scenery/js/nodes/Leaf.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Leaf.ts b/main/scenery/js/nodes/Leaf.ts
--- a/main/scenery/js/nodes/Leaf.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Leaf.ts	(date 1668808229779)
@@ -11,7 +11,7 @@
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import Constructor from '../../../phet-core/js/types/Constructor.js';
 
-const Leaf = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const Leaf = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
 
   return class LeafMixin extends type {
     public constructor( ...args: IntentionalAny[] ) {
Index: main/sun/js/accessibility/AccessibleValueHandler.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleValueHandler.ts b/main/sun/js/accessibility/AccessibleValueHandler.ts
--- a/main/sun/js/accessibility/AccessibleValueHandler.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleValueHandler.ts	(date 1668807766906)
@@ -199,12 +199,12 @@
 type ParentOptions = VoicingOptions & NodeOptions;
 
 export type AccessibleValueHandlerOptions = SelfOptions & VoicingOptions; // do not use ParentOptions here!
-
+type TAccessibleValueHandler = {} & Voicing;
 /**
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleValueHandler = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class AccessibleValueHandler extends Voicing( Type ) {
     private readonly _valueProperty: TProperty<number>;
     private _enabledRangeProperty: TReadOnlyProperty<Range>;
Index: main/sun/js/accessibility/AccessibleSlider.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleSlider.ts b/main/sun/js/accessibility/AccessibleSlider.ts
--- a/main/sun/js/accessibility/AccessibleSlider.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleSlider.ts	(date 1668807766920)
@@ -17,6 +17,7 @@
 import Constructor from '../../../phet-core/js/types/Constructor.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 import optionize from '../../../phet-core/js/optionize.js';
+import ConstructorOf from '../../../phet-core/js/types/ConstructorOf.js';
 import { Node, SceneryEvent } from '../../../scenery/js/imports.js';
 import sun from '../sun.js';
 import AccessibleValueHandler, { AccessibleValueHandlerOptions } from './AccessibleValueHandler.js';
@@ -35,11 +36,13 @@
 
 type AccessibleSliderOptions = SelfOptions & AccessibleValueHandlerOptions;
 
+type TAccessibleSlider = {} & Node;
+
 /**
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleSlider = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   return class AccessibleSlider extends AccessibleValueHandler( Type, optionsArgPosition ) {
 
     private readonly _disposeAccessibleSlider: () => void;
Index: main/scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/util/DelayedMutate.ts b/main/scenery/js/util/DelayedMutate.ts
--- a/main/scenery/js/util/DelayedMutate.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/util/DelayedMutate.ts	(date 1668809813599)
@@ -33,14 +33,14 @@
 import { combineOptions } from '../../../phet-core/js/optionize.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 
+type TDelayedMutate = new() => Node;
+
 /**
  * @param name - A unique name for each call, which customizes the internal key names used to track state
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
-  // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
-  // able to parse that we're using the same keys for each call of this.
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ): TDelayedMutate => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
   const isConstructedKey = `_${name}IsConstructed` as '_fakeIsConstructedType';
 
Index: main/scenery/js/layout/constraints/FlowConfigurable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/constraints/FlowConfigurable.ts b/main/scenery/js/layout/constraints/FlowConfigurable.ts
--- a/main/scenery/js/layout/constraints/FlowConfigurable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/constraints/FlowConfigurable.ts	(date 1668807861905)
@@ -67,7 +67,7 @@
 export type ExternalFlowConfigurableOptions = WithoutNull<FlowConfigurableOptions, Exclude<keyof FlowConfigurableOptions, 'minContentWidth' | 'minContentHeight' | 'maxContentWidth' | 'maxContentHeight'>>;
 
 // (scenery-internal)
-const FlowConfigurable = memoize( <SuperType extends Constructor>( type: SuperType ) => {
+const FlowConfigurable = memoize( <SuperType extends Constructor>( type: SuperType ):any => {
   return class FlowConfigurableMixin extends MarginLayoutConfigurable( type ) {
 
     protected _orientation: Orientation = Orientation.HORIZONTAL;
Index: main/chipper/tsconfig/all/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/chipper/tsconfig/all/tsconfig.json b/main/chipper/tsconfig/common/tsconfig.json
rename from main/chipper/tsconfig/all/tsconfig.json
rename to main/chipper/tsconfig/common/tsconfig.json
--- a/main/chipper/tsconfig/all/tsconfig.json	(revision 2fbbf6b97bcf73b17034d4338f997b267c6b4be4)
+++ b/main/chipper/tsconfig/common/tsconfig.json	(date 1668810122636)
@@ -4,61 +4,61 @@
   // Imported images/mipmaps/sounds are still type checked.
   // This structure was determined in https://github.com/phetsims/chipper/issues/1245
   "include": [
-    "../../../acid-base-solutions/js/**/*",
-    "../../../aqua/js/**/*",
+//    "../../../acid-base-solutions/js/**/*",
+//    "../../../aqua/js/**/*",
     "../../../axon/js/**/*",
     "../../../bamboo/js/**/*",
-    "../../../beers-law-lab/js/**/*",
-    "../../../bending-light/js/**/*",
+//    "../../../beers-law-lab/js/**/*",
+//    "../../../bending-light/js/**/*",
 
     "../../../brand/adapted-from-phet/js/Brand.ts",
     "../../../brand/phet-io/js/Brand.ts",
     "../../../brand/phet/js/Brand.ts",
 
-    "../../../build-a-nucleus/js/**/*",
-    "../../../buoyancy/js/**/*",
-    "../../../calculus-grapher/js/**/*",
-    "../../../center-and-variability/js/**/*",
+//    "../../../build-a-nucleus/js/**/*",
+//    "../../../buoyancy/js/**/*",
+//    "../../../calculus-grapher/js/**/*",
+//    "../../../center-and-variability/js/**/*",
 
     "../../../chipper/js/phet-build-script/phet-build-script.ts",
     "../../../chipper/phet-types.d.ts",
 
-    "../../../circuit-construction-kit-ac/js/**/*",
-    "../../../circuit-construction-kit-common/js/**/*",
-    "../../../circuit-construction-kit-dc/js/**/*",
-    "../../../concentration/js/**/*",
-    "../../../counting-common/js/**/*",
-    "../../../density/js/**/*",
-    "../../../density-buoyancy-common/js/**/*",
-    "../../../diffusion/js/**/*",
+//    "../../../circuit-construction-kit-ac/js/**/*",
+//    "../../../circuit-construction-kit-common/js/**/*",
+//    "../../../circuit-construction-kit-dc/js/**/*",
+//    "../../../concentration/js/**/*",
+//    "../../../counting-common/js/**/*",
+//    "../../../density/js/**/*",
+//    "../../../density-buoyancy-common/js/**/*",
+//    "../../../diffusion/js/**/*",
     "../../../dot/js/**/*",
-    "../../../equality-explorer/js/**/*",
-    "../../../equality-explorer-basics/js/**/*",
-    "../../../equality-explorer-two-variables/js/**/*",
-    "../../../gases-intro/js/**/*",
-    "../../../geometric-optics/js/**/*",
-    "../../../geometric-optics-basics/js/**/*",
-    "../../../gravity-and-orbits/js/**/*",
-    "../../../greenhouse-effect/js/**/*",
+//    "../../../equality-explorer/js/**/*",
+//    "../../../equality-explorer-basics/js/**/*",
+//    "../../../equality-explorer-two-variables/js/**/*",
+//    "../../../gases-intro/js/**/*",
+//    "../../../geometric-optics/js/**/*",
+//    "../../../geometric-optics-basics/js/**/*",
+//    "../../../gravity-and-orbits/js/**/*",
+//    "../../../greenhouse-effect/js/**/*",
     "../../../griddle/js/**/*",
     "../../../joist/js/**/*",
     "../../../kite/js/**/*",
-    "../../../mean-share-and-balance/js/**/*",
+//    "../../../mean-share-and-balance/js/**/*",
     "../../../mobius/js/**/*",
-    "../../../models-of-the-hydrogen-atom/js/**/*",
-    "../../../molecule-polarity/js/**/*",
-    "../../../my-solar-system/js/**/*",
-    "../../../natural-selection/js/**/*",
+//    "../../../models-of-the-hydrogen-atom/js/**/*",
+//    "../../../molecule-polarity/js/**/*",
+//    "../../../my-solar-system/js/**/*",
+//    "../../../natural-selection/js/**/*",
     "../../../nitroglycerin/js/**/*",
-    "../../../number-compare/js/**/*",
-    "../../../number-play/js/**/*",
+//    "../../../number-compare/js/**/*",
+//    "../../../number-play/js/**/*",
 
     "../../../perennial/js/scripts/collate-lint.ts",
     "../../../perennial-alias/js/scripts/collate-lint.ts",
 
-    "../../../ph-scale/js/**/*",
-    "../../../ph-scale-basics/js/**/*",
-    "../../../phet-core/js/**/*",
+//    "../../../ph-scale/js/**/*",
+//    "../../../ph-scale-basics/js/**/*",
+//    "../../../phet-core/js/**/*",
 
     "../../../phet-io/js/TestEventIO.ts",
     "../../../phet-io/js/dataStreamTests.ts",
@@ -67,16 +67,16 @@
     "../../../phet-io-sim-specific/repos/**/*",
     "../../../phet-io-wrappers/js/**/*",
     "../../../phet-io-wrappers/common/**/*",
-    "../../../phet-lib/common/**/*",
+//    "../../../phet-lib/common/**/*",
     "../../../phetcommon/js/**/*",
-    "../../../projectile-motion/js/**/*",
-    "../../../quadrilateral/js/**/*",
+//    "../../../projectile-motion/js/**/*",
+//    "../../../quadrilateral/js/**/*",
     "../../../quake/cordova-plugin-native-vibration/types/index.d.ts",
-    "../../../ratio-and-proportion/js/**/*",
+//    "../../../ratio-and-proportion/js/**/*",
     "../../../scenery/js/**/*",
     "../../../scenery-phet/js/**/*",
     "../../../simula-rasa/js/**/*",
-    "../../../sound/js/**/*",
+//    "../../../sound/js/**/*",
     "../../../studio/js/**/*",
     "../../../sun/js/**/*",
     "../../../tambo/js/**/*",
@@ -89,9 +89,11 @@
     "../../../tangible/js/**/*",
     "../../../twixt/js/**/*",
     "../../../utterance-queue/js/**/*",
-    "../../../vector-addition-equations/js/**/*",
+//    "../../../vector-addition-equations/js/**/*",
     "../../../vegas/js/**/*",
-    "../../../wave-interference/js/**/*",
-    "../../../wilder/js/**/*"
+    "../../../vegas/images/**/*",
+    "../../../vegas/sounds/**/*",
+//    "../../../wave-interference/js/**/*",
+//    "../../../wilder/js/**/*"
   ]
 }
\ No newline at end of file
Index: main/scenery/js/layout/Sizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/Sizable.ts b/main/scenery/js/layout/Sizable.ts
--- a/main/scenery/js/layout/Sizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/Sizable.ts	(date 1668809730879)
@@ -64,7 +64,22 @@
 type ParentOptions = WidthSizableOptions & HeightSizableOptions;
 export type SizableOptions = SelfOptions & ParentOptions;
 
-const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+type TSizable = new() => ( {
+  get preferredSize(): Dimension2 | null;
+  set preferredSize( value: Dimension2 | null );
+  get localPreferredSize(): Dimension2 | null;
+  set localPreferredSize( value: Dimension2 | null );
+  get minimumSize(): Dimension2 | null;
+  set minimumSize( value: Dimension2 | null );
+  get localMinimumSize(): Dimension2 | null;
+  set localMinimumSize( value: Dimension2 | null );
+  get sizable(): boolean;
+  set sizable( value: boolean );
+  get extendsSizable(): boolean;
+  validateLocalPreferredSize(): void;
+} & Node );
+
+const Sizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): TSizable => {
   const SuperExtendedType = WidthSizable( HeightSizable( type ) );
   const SizableTrait = DelayedMutate( 'Sizable', SIZABLE_SELF_OPTION_KEYS, class SizableTrait extends SuperExtendedType {
 
Index: main/scenery/js/layout/WidthSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/WidthSizable.ts b/main/scenery/js/layout/WidthSizable.ts
--- a/main/scenery/js/layout/WidthSizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/WidthSizable.ts	(date 1668810071508)
@@ -55,12 +55,20 @@
   widthSizable?: boolean;
 };
 
+type TWidthSizable = new () => ( {
+  readonly preferredWidthProperty: TinyProperty<number | null>;
+  readonly minimumWidthProperty: TinyProperty<number | null>;
+  readonly localPreferredWidthProperty: TinyProperty<number | null>;
+  readonly localMinimumWidthProperty: TinyProperty<number | null>;
+  readonly isWidthResizableProperty: TinyProperty<boolean>;
+} & Node );
+
 // IMPORTANT: If you're combining this in, typically don't pass options that WidthSizable would take through the
 // constructor. It will hit Node's mutate() likely, and then will fail because we haven't been able to set the
 // values yet. If you're making something WidthSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const WidthSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): TWidthSizable => {
   const WidthSizableTrait = DelayedMutate( 'WidthSizable', WIDTH_SIZABLE_OPTION_KEYS, class WidthSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation
Index: main/sound/js/sound/model/SoundModel.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sound/js/sound/model/SoundModel.ts b/main/sound/js/sound/model/SoundModel.ts
--- a/main/sound/js/sound/model/SoundModel.ts	(revision 1ea219b862fac6b9b03ad457d2e5f3f26de07a65)
+++ b/main/sound/js/sound/model/SoundModel.ts	(date 1668808412497)
@@ -9,6 +9,7 @@
  */
 
 import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
+import Property from '../../../../axon/js/Property.js';
 import NumberProperty from '../../../../axon/js/NumberProperty.js';
 import Bounds2 from '../../../../dot/js/Bounds2.js';
 import Range from '../../../../dot/js/Range.js';
Index: main/scenery/js/accessibility/voicing/ReadingBlock.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/ReadingBlock.ts b/main/scenery/js/accessibility/voicing/ReadingBlock.ts
--- a/main/scenery/js/accessibility/voicing/ReadingBlock.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/ReadingBlock.ts	(date 1668807781487)
@@ -77,7 +77,7 @@
   nameHint: '{{NAME}}. {{HINT}}'
 } );
 
-const ReadingBlock = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const ReadingBlock = <SuperType extends Constructor<Node>>( Type: SuperType ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   const ReadingBlockClass = DelayedMutate( 'ReadingBlock', READING_BLOCK_OPTION_KEYS, class ReadingBlockClass extends Voicing( Type ) {
 
Index: main/gravity-and-orbits/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/gravity-and-orbits/tsconfig.json b/main/gravity-and-orbits/tsconfig.json
--- a/main/gravity-and-orbits/tsconfig.json	(revision fdf0e82a3e91fc961540473c1239ef8b45245d89)
+++ b/main/gravity-and-orbits/tsconfig.json	(date 1668809992005)
@@ -1,6 +1,11 @@
 // This file was automatically generated by grunt update
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [
+    {
+      "path": "../chipper/tsconfig/common/tsconfig.json"
+    }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: main/scenery/js/layout/HeightSizable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/layout/HeightSizable.ts b/main/scenery/js/layout/HeightSizable.ts
--- a/main/scenery/js/layout/HeightSizable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/layout/HeightSizable.ts	(date 1668807824171)
@@ -60,7 +60,7 @@
 // values yet. If you're making something HeightSizable, please use a later mutate() to pass these options through.
 // They WILL be caught by assertions if someone adds one of those options, but it could be a silent bug if no one
 // is yet passing those options through.
-const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+const HeightSizable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ):any => {
   const HeightSizableTrait = DelayedMutate( 'HeightSizable', HEIGHT_SIZABLE_OPTION_KEYS, class HeightSizableTrait extends type {
 
     // parent/local preferred/minimum Properties. See the options above for more documentation
Index: main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1668807766917)
@@ -29,7 +29,11 @@
 
 export type InteractiveHighlightingOptions = SelfOptions;
 
-const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+type IH = {
+  isInteractiveHighlighting: boolean;
+} & Node;
+
+const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   // @ts-ignore
   assert && assert( !Type._mixesInteractiveHighlighting, 'InteractiveHighlighting is already added to this Type' );
Index: main/scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/Voicing.ts b/main/scenery/js/accessibility/voicing/Voicing.ts
--- a/main/scenery/js/accessibility/voicing/Voicing.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/accessibility/voicing/Voicing.ts	(date 1668807766913)
@@ -105,7 +105,47 @@
                                                  ResponsePacketOptions[PropertyName];
 };
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+// type TVoicing = {
+//   voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+//
+//   initialize( ...args: IntentionalAny[] ): this;
+//   voicingSpeakFullResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakNameResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakObjectResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+//   voicingSpeakHintResponse( providedOptions?: SpeakingOptions ): void;
+//   setVoicingNameResponse( response: VoicingResponse ): void;
+//   set voicingNameResponse( response: VoicingResponse );
+//   get voicingNameResponse(): ResolvedResponse;
+//   getVoicingNameResponse(): ResolvedResponse;
+//   setVoicingObjectResponse( response: VoicingResponse ): void;
+//   set voicingObjectResponse( response: VoicingResponse );
+//   get voicingObjectResponse(): ResolvedResponse;
+//   getVoicingObjectResponse(): ResolvedResponse;
+//   setVoicingContextResponse( response: VoicingResponse ): void;
+//   set voicingContextResponse( response: VoicingResponse );
+//   get voicingContextResponse(): ResolvedResponse;
+//   getVoicingContextResponse(): ResolvedResponse;
+//   setVoicingHintResponse( response: VoicingResponse ): void;
+//   set voicingHintResponse( response: VoicingResponse );
+//   get voicingHintResponse(): ResolvedResponse;
+//   getVoicingHintResponse(): ResolvedResponse;
+//   setVoicingIgnoreVoicingManagerProperties( ignoreProperties: boolean ): void;
+//   set voicingIgnoreVoicingManagerProperties( ignoreProperties: boolean );
+//   get voicingIgnoreVoicingManagerProperties(): boolean;
+//   getVoicingIgnoreVoicingManagerProperties(): boolean;
+//   setVoicingResponsePatternCollection( patterns: ResponsePatternCollection ): void;
+//   set voicingResponsePatternCollection( patterns: ResponsePatternCollection );
+//   get voicingResponsePatternCollection(): ResponsePatternCollection;
+//   getVoicingResponsePatternCollection(): ResponsePatternCollection;
+//   setVoicingUtterance( utterance: Utterance ): void;
+//   set voicingUtterance( utterance: Utterance );
+//   get voicingUtterance(): Utterance;
+//   getVoicingUtterance(): Utterance;
+// } & Node;
+
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ): any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
Index: main/sun/js/Popupable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/Popupable.ts b/main/sun/js/Popupable.ts
--- a/main/sun/js/Popupable.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/Popupable.ts	(date 1668808313700)
@@ -42,7 +42,7 @@
 };
 export type PopupableOptions = SelfOptions & PickOptional<NodeOptions, 'tandem'>;
 
-const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   return class extends type {
 
Index: main/chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/chipper/tsconfig-core.json b/main/chipper/tsconfig-core.json
--- a/main/chipper/tsconfig-core.json	(revision 2fbbf6b97bcf73b17034d4338f997b267c6b4be4)
+++ b/main/chipper/tsconfig-core.json	(date 1668808797010)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+    "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: main/scenery/js/nodes/Paintable.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Paintable.ts b/main/scenery/js/nodes/Paintable.ts
--- a/main/scenery/js/nodes/Paintable.ts	(revision 40053bc115a518e922683bf9fe7957d54c0a5559)
+++ b/main/scenery/js/nodes/Paintable.ts	(date 1668809021280)
@@ -67,7 +67,10 @@
 
 const PAINTABLE_DRAWABLE_MARK_FLAGS = [ 'fill', 'stroke', 'lineWidth', 'lineOptions', 'cachedPaints' ];
 
-const Paintable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ) => {
+type TPaintable = new() => ( {
+  _fill: TPaint;
+} & Node );
+const Paintable = memoize( <SuperType extends Constructor<Node>>( type: SuperType ): TPaintable => {
   assert && assert( _.includes( inheritance( type ), Node ), 'Only Node subtypes should mix Paintable' );
 
   return class PaintableMixin extends type {
Index: main/sun/js/accessibility/AccessibleNumberSpinner.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/sun/js/accessibility/AccessibleNumberSpinner.ts b/main/sun/js/accessibility/AccessibleNumberSpinner.ts
--- a/main/sun/js/accessibility/AccessibleNumberSpinner.ts	(revision 8e3cd4426682e0882c11510a63ce34b783100e80)
+++ b/main/sun/js/accessibility/AccessibleNumberSpinner.ts	(date 1668808293295)
@@ -46,7 +46,7 @@
  * @param Type
  * @param optionsArgPosition - zero-indexed number that the options argument is provided at
  */
-const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const AccessibleNumberSpinner = <SuperType extends Constructor<Node>>( Type: SuperType, optionsArgPosition: number ):any => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
 
   return class AccessibleNumberSpinner extends AccessibleValueHandler( Type, optionsArgPosition ) {
 

@marlitas
Copy link
Contributor

We did progress and next need to create types for mixins:

Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision 0fd51f03ecc13c1855a7e2017c5394c7329ff6fb)
+++ b/chipper/tsconfig-core.json	(date 1669139206522)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+        "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: chipper/tsconfig/common-code/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig/common-code/tsconfig.json b/chipper/tsconfig/common-code/tsconfig.json
new file mode 100644
--- /dev/null	(date 1669140266449)
+++ b/chipper/tsconfig/common-code/tsconfig.json	(date 1669140266449)
@@ -0,0 +1,70 @@
+{
+  "extends": "../../tsconfig-core.json",
+  // Explicitly list all entry points that we want to type check.
+  // Imported images/mipmaps/sounds are still type checked.
+  // This structure was determined in https://github.com/phetsims/chipper/issues/1245
+  "include": [
+    "../../../axon/js/**/*",
+    "../../../bamboo/js/**/*",
+
+    "../../../brand/adapted-from-phet/js/Brand.ts",
+    "../../../brand/phet-io/js/Brand.ts",
+    "../../../brand/phet/js/Brand.ts",
+    "../../../brand/phet/images/**/*",
+    "../../../brand/phet-io/images/**/*",
+    "../../../brand/adapted-from-phet/images/**/*",
+    "../../../brand/js/**/*",
+
+    "../../../chipper/js/phet-build-script/phet-build-script.ts",
+    "../../../chipper/phet-types.d.ts",
+    "../../../chipper/js/sim-tests/qunitStart.js",
+    "../../../chipper/js/getStringModule.ts",
+    "../../../chipper/js/data/localeInfoModule.js",
+    "../../../chipper/js/chipper.ts",
+    "../../../chipper/js/LocalizedString.ts",
+
+    "../../../dot/js/**/*",
+    "../../../griddle/js/**/*",
+    "../../../joist/js/**/*",
+    "../../../joist/sounds/**/*",
+    "../../../joist/images/**/*",
+    "../../../kite/js/**/*",
+    "../../../mobius/js/**/*",
+    "../../../nitroglycerin/js/**/*",
+
+    "../../../perennial/js/scripts/collate-lint.ts",
+    "../../../perennial-alias/js/scripts/collate-lint.ts",
+
+    "../../../phet-core/js/**/*",
+
+    "../../../phet-io/js/**/*",
+
+    "../../../phet-io-sim-specific/repos/**/*",
+    "../../../phet-io-wrappers/js/**/*",
+    "../../../phet-io-wrappers/common/**/*",
+    "../../../phet-lib/common/**/*",
+    "../../../phetcommon/js/**/*",
+    "../../../quake/cordova-plugin-native-vibration/types/index.d.ts",
+    "../../../scenery/js/**/*",
+    "../../../scenery-phet/js/**/*",
+    "../../../scenery-phet/images/**/*",
+    "../../../scenery-phet/sounds/**/*",
+    "../../../scenery-phet/mipmaps/**/*",
+    "../../../sherpa/js/**/*",
+    "../../../sherpa/lib/lodash-4.17.4.min.js",
+    "../../../sherpa/lib/game-up-camera-1.0.0.js",
+    "../../../studio/js/**/*",
+    "../../../sun/js/**/*",
+    "../../../tambo/js/**/*",
+    "../../../tambo/images/**/*",
+    "../../../tambo/sounds/**/*",
+    "../../../tappi/js/**/*",
+    "../../../tandem/js/**/*",
+    "../../../tangible/js/**/*",
+    "../../../twixt/js/**/*",
+    "../../../utterance-queue/js/**/*",
+    "../../../vegas/js/**/*",
+    "../../../vegas/images/**/*",
+    "../../../vegas/sounds/**/*"
+  ]
+}
\ No newline at end of file
Index: mean-share-and-balance/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/mean-share-and-balance/tsconfig.json b/mean-share-and-balance/tsconfig.json
--- a/mean-share-and-balance/tsconfig.json	(revision cfc08169e07b7f117d70021767f9d3f43e1787d6)
+++ b/mean-share-and-balance/tsconfig.json	(date 1669139141956)
@@ -1,6 +1,10 @@
 // This file was automatically generated by grunt update
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [ {
+    "path": "../chipper/tsconfig/common-code/tsconfig.json"
+  }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",

@zepumph
Copy link
Member

zepumph commented Dec 9, 2022

@samreid and I got a bit further with mixins today, but can't seem to work out the hierarchy in voicing right now. In this patch there is good progress, but the next steps are that DelayedMutate's doesn't take into account the parent type at all, so the subclass (Voicing) thinks it doesn't fulfill the needs of being Node-like.

Index: scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/DelayedMutate.ts b/scenery/js/util/DelayedMutate.ts
--- a/scenery/js/util/DelayedMutate.ts	(revision 5816813afb3d1947a8b26e5454c8c2a8c0f6ddc2)
+++ b/scenery/js/util/DelayedMutate.ts	(date 1670623107754)
@@ -33,12 +33,16 @@
 import { combineOptions } from '../../../phet-core/js/optionize.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 
+type DelayedMutateType = {
+  mutate( options?: NodeOptions ): DelayedMutateType;
+};
+
 /**
  * @param name - A unique name for each call, which customizes the internal key names used to track state
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ): Constructor<DelayedMutateType> => {
   // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
   // able to parse that we're using the same keys for each call of this.
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
Index: mean-share-and-balance/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/mean-share-and-balance/tsconfig.json b/mean-share-and-balance/tsconfig.json
--- a/mean-share-and-balance/tsconfig.json	(revision 1601d4fd16ec9ab0d4aaa4b91b546d220d91a263)
+++ b/mean-share-and-balance/tsconfig.json	(date 1670621163250)
@@ -1,6 +1,10 @@
 // This file was automatically generated by grunt update
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [ {
+    "path": "../chipper/tsconfig/common-code/tsconfig.json"
+  }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: chipper/tsconfig/common-code/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig/common-code/tsconfig.json b/chipper/tsconfig/common-code/tsconfig.json
new file mode 100644
--- /dev/null	(date 1670621163237)
+++ b/chipper/tsconfig/common-code/tsconfig.json	(date 1670621163237)
@@ -0,0 +1,70 @@
+{
+  "extends": "../../tsconfig-core.json",
+  // Explicitly list all entry points that we want to type check.
+  // Imported images/mipmaps/sounds are still type checked.
+  // This structure was determined in https://github.com/phetsims/chipper/issues/1245
+  "include": [
+    "../../../axon/js/**/*",
+    "../../../bamboo/js/**/*",
+
+    "../../../brand/adapted-from-phet/js/Brand.ts",
+    "../../../brand/phet-io/js/Brand.ts",
+    "../../../brand/phet/js/Brand.ts",
+    "../../../brand/phet/images/**/*",
+    "../../../brand/phet-io/images/**/*",
+    "../../../brand/adapted-from-phet/images/**/*",
+    "../../../brand/js/**/*",
+
+    "../../../chipper/js/phet-build-script/phet-build-script.ts",
+    "../../../chipper/phet-types.d.ts",
+    "../../../chipper/js/sim-tests/qunitStart.js",
+    "../../../chipper/js/getStringModule.ts",
+    "../../../chipper/js/data/localeInfoModule.js",
+    "../../../chipper/js/chipper.ts",
+    "../../../chipper/js/LocalizedString.ts",
+
+    "../../../dot/js/**/*",
+    "../../../griddle/js/**/*",
+    "../../../joist/js/**/*",
+    "../../../joist/sounds/**/*",
+    "../../../joist/images/**/*",
+    "../../../kite/js/**/*",
+    "../../../mobius/js/**/*",
+    "../../../nitroglycerin/js/**/*",
+
+    "../../../perennial/js/scripts/collate-lint.ts",
+    "../../../perennial-alias/js/scripts/collate-lint.ts",
+
+    "../../../phet-core/js/**/*",
+
+    "../../../phet-io/js/**/*",
+
+    "../../../phet-io-sim-specific/repos/**/*",
+    "../../../phet-io-wrappers/js/**/*",
+    "../../../phet-io-wrappers/common/**/*",
+    "../../../phet-lib/common/**/*",
+    "../../../phetcommon/js/**/*",
+    "../../../quake/cordova-plugin-native-vibration/types/index.d.ts",
+    "../../../scenery/js/**/*",
+    "../../../scenery-phet/js/**/*",
+    "../../../scenery-phet/images/**/*",
+    "../../../scenery-phet/sounds/**/*",
+    "../../../scenery-phet/mipmaps/**/*",
+    "../../../sherpa/js/**/*",
+    "../../../sherpa/lib/lodash-4.17.4.min.js",
+    "../../../sherpa/lib/game-up-camera-1.0.0.js",
+    "../../../studio/js/**/*",
+    "../../../sun/js/**/*",
+    "../../../tambo/js/**/*",
+    "../../../tambo/images/**/*",
+    "../../../tambo/sounds/**/*",
+    "../../../tappi/js/**/*",
+    "../../../tandem/js/**/*",
+    "../../../tangible/js/**/*",
+    "../../../twixt/js/**/*",
+    "../../../utterance-queue/js/**/*",
+    "../../../vegas/js/**/*",
+    "../../../vegas/images/**/*",
+    "../../../vegas/sounds/**/*"
+  ]
+}
\ No newline at end of file
Index: scenery/js/util/TestMixin.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/util/TestMixin.ts b/scenery/js/util/TestMixin.ts
new file mode 100644
--- /dev/null	(date 1670623107743)
+++ b/scenery/js/util/TestMixin.ts	(date 1670623107743)
@@ -0,0 +1,29 @@
+// Copyright 2022, University of Colorado Boulder
+
+import Constructor from '../../../phet-core/js/types/Constructor.js';
+import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+
+type TestMixinType = {
+  oneFunc( one: boolean ): void;
+};
+
+type Creator<T> = Constructor<TestMixinType & T>;
+/**
+ * @param name - A unique name for each call, which customizes the internal key names used to track state
+ * @param keys - An array of the mutate option names that should be delayed
+ * @param type - The class we're mixing into
+ */
+const TestMixin = <SuperType extends Constructor<IntentionalAny>>( name: string, keys: string[], type: SuperType ): Creator<SuperType> => {
+  return class TestMixinMixin extends type {
+    public constructor( ...args: IntentionalAny[] ) {
+      super( ...args );
+      console.log( 'creating' );
+    }
+
+    public oneFunc( one: boolean ): void {
+      console.log( 'hi' );
+    }
+  };
+};
+
+export default TestMixin;
Index: scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/Voicing.ts b/scenery/js/accessibility/voicing/Voicing.ts
--- a/scenery/js/accessibility/voicing/Voicing.ts	(revision 5816813afb3d1947a8b26e5454c8c2a8c0f6ddc2)
+++ b/scenery/js/accessibility/voicing/Voicing.ts	(date 1670623107767)
@@ -98,7 +98,99 @@
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+export type MyVoicing = {
+  new( ...args: any ): MyVoicing & Node;
+
+  initialize( ...args: IntentionalAny[] ): MyVoicing;
+
+  voicingSpeakFullResponse( providedOptions?: SpeakingOptions ): void;
+  voicingSpeakResponse( providedOptions?: SpeakingOptions ): void;
+  voicingSpeakNameResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakObjectResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakHintResponse( providedOptions?: SpeakingOptions ): void;
+
+  setVoicingNameResponse( response: VoicingResponse ): void;
+
+  set voicingNameResponse( response: VoicingResponse );
+
+  get voicingNameResponse(): ResolvedResponse;
+
+  getVoicingNameResponse(): ResolvedResponse;
+
+  setVoicingObjectResponse( response: VoicingResponse ): void;
+
+  set voicingObjectResponse( response: VoicingResponse );
+
+  get voicingObjectResponse(): ResolvedResponse;
+
+  getVoicingObjectResponse(): ResolvedResponse;
+
+  setVoicingContextResponse( response: VoicingResponse ): void;
+
+  set voicingContextResponse( response: VoicingResponse );
+
+  get voicingContextResponse(): ResolvedResponse;
+
+  getVoicingContextResponse(): ResolvedResponse;
+
+  setVoicingHintResponse( response: VoicingResponse ): void;
+
+  set voicingHintResponse( response: VoicingResponse );
+
+  get voicingHintResponse(): ResolvedResponse;
+
+  getVoicingHintResponse(): ResolvedResponse;
+
+  setVoicingIgnoreVoicingManagerProperties( ignoreProperties: boolean ): void;
+
+  set voicingIgnoreVoicingManagerProperties( ignoreProperties: boolean );
+
+  get voicingIgnoreVoicingManagerProperties(): boolean;
+
+  getVoicingIgnoreVoicingManagerProperties(): boolean;
+
+  setVoicingResponsePatternCollection( patterns: ResponsePatternCollection ): void;
+
+  set voicingResponsePatternCollection( patterns: ResponsePatternCollection );
+
+  get voicingResponsePatternCollection(): ResponsePatternCollection;
+
+  getVoicingResponsePatternCollection(): ResponsePatternCollection;
+
+  setVoicingUtterance( utterance: Utterance ): void;
+
+  set voicingUtterance( utterance: Utterance );
+
+  get voicingUtterance(): Utterance;
+
+  getVoicingUtterance(): Utterance;
+
+  getVoicingCanSpeakProperty(): TinyProperty<boolean>;
+
+  get voicingCanSpeakProperty(): TinyProperty<boolean>;
+
+  setVoicingFocusListener( focusListener: SceneryListenerFunction<FocusEvent> | null ): void;
+
+  set voicingFocusListener( focusListener: SceneryListenerFunction<FocusEvent> | null );
+
+  get voicingFocusListener(): SceneryListenerFunction<FocusEvent> | null;
+
+  getVoicingFocusListener(): SceneryListenerFunction<FocusEvent> | null;
+
+  defaultFocusListener(): void;
+
+  get isVoicing(): boolean;
+
+  dispose(): void;
+
+  clean(): void;
+} & Node;
+
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ): Constructor<MyVoicing> => {
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
@@ -668,7 +760,7 @@
  * if the voicingNode is globally visible and voicingVisible in the display.
  * @static
  */
-Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: MyVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
   if ( !existingCanAnnounceProperties.includes( voicingNode.voicingCanSpeakProperty ) ) {
     utterance.voicingCanAnnounceProperties = existingCanAnnounceProperties.concat( [ voicingNode.voicingCanSpeakProperty ] );
@@ -679,7 +771,7 @@
  * Remove a voicingNode's voicingCanSpeakProperty from the Utterance.
  * @static
  */
-Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: MyVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
   const index = existingCanAnnounceProperties.indexOf( voicingNode.voicingCanSpeakProperty );
   assert && assert( index > -1, 'voicingNode.voicingCanSpeakProperty is not on the Utterance, was it not registered?' );
Index: scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision 5816813afb3d1947a8b26e5454c8c2a8c0f6ddc2)
+++ b/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1670623107778)
@@ -29,7 +29,7 @@
 
 export type InteractiveHighlightingOptions = SelfOptions;
 
-const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ): Constructor<Node> => {
 
   // @ts-expect-error
   assert && assert( !Type._mixesInteractiveHighlighting, 'InteractiveHighlighting is already added to this Type' );
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision 62284603a71a26f82ffebfb51e558ede11f7c14a)
+++ b/chipper/tsconfig-core.json	(date 1670621163245)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+        "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

@samreid
Copy link
Member Author

samreid commented Dec 19, 2022

Here are my top 30 tsc times from precommit hooks in December.

118024
97490
97347
97167
96873
94633
90101
88478
85447
85205
84309
82426
81211
81163
79102
79002
78840
19337
16472
13016
11959
11552
11398
11394
11321
11306
11273
11205
11196
10735

I should note I also run tsc without the precommit hooks, and it is often taking 80+ seconds. This is very unfortunate, and it makes me want to bump the priority of this issue. But even getting to a point where we can test the performance of this approach will be time consuming.

@samreid
Copy link
Member Author

samreid commented Jan 3, 2023

Adding this to DelayedMutateType helps the patch above a lot.

type DelayedMutateType = {
  mutate( options?: NodeOptions ): DelayedMutateType;
} & Node;

@samreid
Copy link
Member Author

samreid commented Jan 3, 2023

403 type errors in this patch:

Subject: [PATCH] Rename stateToArgsForConstructor => stateObjectToCreateElementArguments, see https://github.com/phetsims/tandem/issues/287
---
Index: main/scenery/js/nodes/Node.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/nodes/Node.ts b/main/scenery/js/nodes/Node.ts
--- a/main/scenery/js/nodes/Node.ts	(revision ab5e79db4e89786a9c1ecbc9f00fed63fabcf46d)
+++ b/main/scenery/js/nodes/Node.ts	(date 1672725402542)
@@ -6395,7 +6395,7 @@
    * @param spaces - Whitespace to add
    * @param [includeChildren]
    */
-  public override toString( spaces: string, includeChildren?: boolean ): string {
+  public override toString(): string {
     return `${this.constructor.name}#${this.id}`;
   }
 
Index: main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts
--- a/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(revision ab5e79db4e89786a9c1ecbc9f00fed63fabcf46d)
+++ b/main/scenery/js/accessibility/voicing/InteractiveHighlighting.ts	(date 1672725248886)
@@ -29,7 +29,7 @@
 
 export type InteractiveHighlightingOptions = SelfOptions;
 
-const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const InteractiveHighlighting = <SuperType extends Constructor<Node>>( Type: SuperType ): Constructor<Node> => {
 
   // @ts-expect-error
   assert && assert( !Type._mixesInteractiveHighlighting, 'InteractiveHighlighting is already added to this Type' );
Index: main/mean-share-and-balance/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/mean-share-and-balance/tsconfig.json b/main/mean-share-and-balance/tsconfig.json
--- a/main/mean-share-and-balance/tsconfig.json	(revision 58465f237fb6ff178f1b10ebca3ecd082f40ed22)
+++ b/main/mean-share-and-balance/tsconfig.json	(date 1672725248881)
@@ -1,6 +1,10 @@
 // This file was automatically generated by grunt update
 {
   "extends": "../chipper/tsconfig-core.json",
+  "references": [ {
+    "path": "../chipper/tsconfig/common-code/tsconfig.json"
+  }
+  ],
   "include": [
     "js/**/*",
     "images/**/*",
Index: main/scenery/js/util/DelayedMutate.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/util/DelayedMutate.ts b/main/scenery/js/util/DelayedMutate.ts
--- a/main/scenery/js/util/DelayedMutate.ts	(revision ab5e79db4e89786a9c1ecbc9f00fed63fabcf46d)
+++ b/main/scenery/js/util/DelayedMutate.ts	(date 1672725314995)
@@ -33,12 +33,16 @@
 import { combineOptions } from '../../../phet-core/js/optionize.js';
 import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
 
+type DelayedMutateType = {
+  mutate( options?: NodeOptions ): DelayedMutateType;
+} & Node;
+
 /**
  * @param name - A unique name for each call, which customizes the internal key names used to track state
  * @param keys - An array of the mutate option names that should be delayed
  * @param type - The class we're mixing into
  */
-const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+const DelayedMutate = <SuperType extends Constructor<Node>>( name: string, keys: string[], type: SuperType ): Constructor<DelayedMutateType> => {
   // We typecast these to strings to satisfy the type-checker without large amounts of grief. It doesn't seem to be
   // able to parse that we're using the same keys for each call of this.
   const pendingOptionsKey = `_${name}PendingOptions` as '_fakePendingOptionsType';
Index: main/scenery/js/accessibility/voicing/Voicing.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/accessibility/voicing/Voicing.ts b/main/scenery/js/accessibility/voicing/Voicing.ts
--- a/main/scenery/js/accessibility/voicing/Voicing.ts	(revision ab5e79db4e89786a9c1ecbc9f00fed63fabcf46d)
+++ b/main/scenery/js/accessibility/voicing/Voicing.ts	(date 1672725248890)
@@ -98,7 +98,99 @@
   utterance?: SelfOptions['voicingUtterance'];
 } & SpeakableResolvedOptions;
 
-const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
+export type MyVoicing = {
+  new( ...args: any ): MyVoicing & Node;
+
+  initialize( ...args: IntentionalAny[] ): MyVoicing;
+
+  voicingSpeakFullResponse( providedOptions?: SpeakingOptions ): void;
+  voicingSpeakResponse( providedOptions?: SpeakingOptions ): void;
+  voicingSpeakNameResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakObjectResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakContextResponse( providedOptions?: SpeakingOptions ): void;
+
+  voicingSpeakHintResponse( providedOptions?: SpeakingOptions ): void;
+
+  setVoicingNameResponse( response: VoicingResponse ): void;
+
+  set voicingNameResponse( response: VoicingResponse );
+
+  get voicingNameResponse(): ResolvedResponse;
+
+  getVoicingNameResponse(): ResolvedResponse;
+
+  setVoicingObjectResponse( response: VoicingResponse ): void;
+
+  set voicingObjectResponse( response: VoicingResponse );
+
+  get voicingObjectResponse(): ResolvedResponse;
+
+  getVoicingObjectResponse(): ResolvedResponse;
+
+  setVoicingContextResponse( response: VoicingResponse ): void;
+
+  set voicingContextResponse( response: VoicingResponse );
+
+  get voicingContextResponse(): ResolvedResponse;
+
+  getVoicingContextResponse(): ResolvedResponse;
+
+  setVoicingHintResponse( response: VoicingResponse ): void;
+
+  set voicingHintResponse( response: VoicingResponse );
+
+  get voicingHintResponse(): ResolvedResponse;
+
+  getVoicingHintResponse(): ResolvedResponse;
+
+  setVoicingIgnoreVoicingManagerProperties( ignoreProperties: boolean ): void;
+
+  set voicingIgnoreVoicingManagerProperties( ignoreProperties: boolean );
+
+  get voicingIgnoreVoicingManagerProperties(): boolean;
+
+  getVoicingIgnoreVoicingManagerProperties(): boolean;
+
+  setVoicingResponsePatternCollection( patterns: ResponsePatternCollection ): void;
+
+  set voicingResponsePatternCollection( patterns: ResponsePatternCollection );
+
+  get voicingResponsePatternCollection(): ResponsePatternCollection;
+
+  getVoicingResponsePatternCollection(): ResponsePatternCollection;
+
+  setVoicingUtterance( utterance: Utterance ): void;
+
+  set voicingUtterance( utterance: Utterance );
+
+  get voicingUtterance(): Utterance;
+
+  getVoicingUtterance(): Utterance;
+
+  getVoicingCanSpeakProperty(): TinyProperty<boolean>;
+
+  get voicingCanSpeakProperty(): TinyProperty<boolean>;
+
+  setVoicingFocusListener( focusListener: SceneryListenerFunction<FocusEvent> | null ): void;
+
+  set voicingFocusListener( focusListener: SceneryListenerFunction<FocusEvent> | null );
+
+  get voicingFocusListener(): SceneryListenerFunction<FocusEvent> | null;
+
+  getVoicingFocusListener(): SceneryListenerFunction<FocusEvent> | null;
+
+  defaultFocusListener(): void;
+
+  get isVoicing(): boolean;
+
+  dispose(): void;
+
+  clean(): void;
+} & Node;
+
+const Voicing = <SuperType extends Constructor<Node>>( Type: SuperType ): Constructor<MyVoicing> => {
 
   assert && assert( _.includes( inheritance( Type ), Node ), 'Only Node subtypes should compose Voicing' );
 
@@ -668,7 +760,7 @@
  * if the voicingNode is globally visible and voicingVisible in the display.
  * @static
  */
-Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.registerUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: MyVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
   if ( !existingCanAnnounceProperties.includes( voicingNode.voicingCanSpeakProperty ) ) {
     utterance.voicingCanAnnounceProperties = existingCanAnnounceProperties.concat( [ voicingNode.voicingCanSpeakProperty ] );
@@ -679,7 +771,7 @@
  * Remove a voicingNode's voicingCanSpeakProperty from the Utterance.
  * @static
  */
-Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: VoicingNode ) => {
+Voicing.unregisterUtteranceToVoicingNode = ( utterance: Utterance, voicingNode: MyVoicing ) => {
   const existingCanAnnounceProperties = utterance.voicingCanAnnounceProperties;
   const index = existingCanAnnounceProperties.indexOf( voicingNode.voicingCanSpeakProperty );
   assert && assert( index > -1, 'voicingNode.voicingCanSpeakProperty is not on the Utterance, was it not registered?' );
Index: main/scenery/js/util/TestMixin.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/scenery/js/util/TestMixin.ts b/main/scenery/js/util/TestMixin.ts
new file mode 100644
--- /dev/null	(date 1672725248897)
+++ b/main/scenery/js/util/TestMixin.ts	(date 1672725248897)
@@ -0,0 +1,29 @@
+// Copyright 2022, University of Colorado Boulder
+
+import Constructor from '../../../phet-core/js/types/Constructor.js';
+import IntentionalAny from '../../../phet-core/js/types/IntentionalAny.js';
+
+type TestMixinType = {
+  oneFunc( one: boolean ): void;
+};
+
+type Creator<T> = Constructor<TestMixinType & T>;
+/**
+ * @param name - A unique name for each call, which customizes the internal key names used to track state
+ * @param keys - An array of the mutate option names that should be delayed
+ * @param type - The class we're mixing into
+ */
+const TestMixin = <SuperType extends Constructor<IntentionalAny>>( name: string, keys: string[], type: SuperType ): Creator<SuperType> => {
+  return class TestMixinMixin extends type {
+    public constructor( ...args: IntentionalAny[] ) {
+      super( ...args );
+      console.log( 'creating' );
+    }
+
+    public oneFunc( one: boolean ): void {
+      console.log( 'hi' );
+    }
+  };
+};
+
+export default TestMixin;
Index: main/chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/chipper/tsconfig-core.json b/main/chipper/tsconfig-core.json
--- a/main/chipper/tsconfig-core.json	(revision da4b632c9232677f98f2c81b1388d37f89cc63ca)
+++ b/main/chipper/tsconfig-core.json	(date 1672725248877)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+        "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: main/chipper/tsconfig/common-code/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/main/chipper/tsconfig/common-code/tsconfig.json b/main/chipper/tsconfig/common-code/tsconfig.json
new file mode 100644
--- /dev/null	(date 1672725248873)
+++ b/main/chipper/tsconfig/common-code/tsconfig.json	(date 1672725248873)
@@ -0,0 +1,70 @@
+{
+  "extends": "../../tsconfig-core.json",
+  // Explicitly list all entry points that we want to type check.
+  // Imported images/mipmaps/sounds are still type checked.
+  // This structure was determined in https://github.com/phetsims/chipper/issues/1245
+  "include": [
+    "../../../axon/js/**/*",
+    "../../../bamboo/js/**/*",
+
+    "../../../brand/adapted-from-phet/js/Brand.ts",
+    "../../../brand/phet-io/js/Brand.ts",
+    "../../../brand/phet/js/Brand.ts",
+    "../../../brand/phet/images/**/*",
+    "../../../brand/phet-io/images/**/*",
+    "../../../brand/adapted-from-phet/images/**/*",
+    "../../../brand/js/**/*",
+
+    "../../../chipper/js/phet-build-script/phet-build-script.ts",
+    "../../../chipper/phet-types.d.ts",
+    "../../../chipper/js/sim-tests/qunitStart.js",
+    "../../../chipper/js/getStringModule.ts",
+    "../../../chipper/js/data/localeInfoModule.js",
+    "../../../chipper/js/chipper.ts",
+    "../../../chipper/js/LocalizedString.ts",
+
+    "../../../dot/js/**/*",
+    "../../../griddle/js/**/*",
+    "../../../joist/js/**/*",
+    "../../../joist/sounds/**/*",
+    "../../../joist/images/**/*",
+    "../../../kite/js/**/*",
+    "../../../mobius/js/**/*",
+    "../../../nitroglycerin/js/**/*",
+
+    "../../../perennial/js/scripts/collate-lint.ts",
+    "../../../perennial-alias/js/scripts/collate-lint.ts",
+
+    "../../../phet-core/js/**/*",
+
+    "../../../phet-io/js/**/*",
+
+    "../../../phet-io-sim-specific/repos/**/*",
+    "../../../phet-io-wrappers/js/**/*",
+    "../../../phet-io-wrappers/common/**/*",
+    "../../../phet-lib/common/**/*",
+    "../../../phetcommon/js/**/*",
+    "../../../quake/cordova-plugin-native-vibration/types/index.d.ts",
+    "../../../scenery/js/**/*",
+    "../../../scenery-phet/js/**/*",
+    "../../../scenery-phet/images/**/*",
+    "../../../scenery-phet/sounds/**/*",
+    "../../../scenery-phet/mipmaps/**/*",
+    "../../../sherpa/js/**/*",
+    "../../../sherpa/lib/lodash-4.17.4.min.js",
+    "../../../sherpa/lib/game-up-camera-1.0.0.js",
+    "../../../studio/js/**/*",
+    "../../../sun/js/**/*",
+    "../../../tambo/js/**/*",
+    "../../../tambo/images/**/*",
+    "../../../tambo/sounds/**/*",
+    "../../../tappi/js/**/*",
+    "../../../tandem/js/**/*",
+    "../../../tangible/js/**/*",
+    "../../../twixt/js/**/*",
+    "../../../utterance-queue/js/**/*",
+    "../../../vegas/js/**/*",
+    "../../../vegas/images/**/*",
+    "../../../vegas/sounds/**/*"
+  ]
+}
\ No newline at end of file

@samreid
Copy link
Member Author

samreid commented Jan 27, 2023

TypeScript 5.0 beta was released today, I wonder if that would simplify anything here? There were some notes about changes for emitDeclaration in tsc --build but that may just be about command line options. Also, TypeScript 5.0 claims to have speed improvements like 10%-20% which may help.

@zepumph
Copy link
Member

zepumph commented Jan 5, 2024

In #1415 (comment), @samreid and I spent some time understanding just how many entry points we can add to tsconfig/all/tsconfig.json before we are no longer able to type check because it is too big to fit into memory (heap crash). We believe that it ~30 more entrypoints could be added, but we currently have 60 sims in javascript with no entry points in that file (not to mention new sims always being created starting in typescript).

This should bump the priority of this issue, because project references are the way out of storing the entirety of the codebases type information in memory. We always knew this day would come eventually, but let's raise the priority of this issue well BEFORE we are nearing our 30th new entrypoint over there.

The primary reason this is a higher priority is because eslint uses the all config for its type info. Perhaps a workaround would be to have a smarter way to specify the eslint config's project path (maybe custom to the lint task being done?).

We'd like to bring this up to dev meeting to add to the proposed planning topics, mostly to get this on peoples radar.

@samreid
Copy link
Member Author

samreid commented Mar 11, 2024

@marlitas indicated that @samreid and @matthew-blackman will likely be working on this in upcoming iterations.

@samreid samreid self-assigned this Mar 11, 2024
@samreid
Copy link
Member Author

samreid commented Mar 11, 2024

I tested the hypothesis that if we put all of the mixins in one bundle, then they can still infer (from the dynamic part) properly. However, with this patch:

Subject: [PATCH] Simplify the background gradient, and make it non-scaled, see https://github.com/phetsims/projectile-data-lab/issues/178
---
Index: chipper/tsconfig-core.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig-core.json b/chipper/tsconfig-core.json
--- a/chipper/tsconfig-core.json	(revision 004565e8ca9fe881f051c0ddfab9e618bc39ea2a)
+++ b/chipper/tsconfig-core.json	(date 1710195233041)
@@ -14,17 +14,17 @@
     "allowJs": true,                             /* Allow javascript files to be compiled. */
     "checkJs": false,                            /* Report errors in .js files. */
     "jsx": "react",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
-    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
+    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
     "sourceMap": false,                           /* Generates corresponding '.map' file. */
     "outDir": "../chipper/dist/outDir",     /* Redirect output structure to the directory. */
     "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
     // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
-     "composite": false,                             /* Enable project compilation */
+     "composite": true,                             /* Enable project compilation */
     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
     // "removeComments": true,                      /* Do not emit comments to output. */
-    "noEmit": true,                              /* Do not emit outputs. */
-    //    "emitDeclarationOnly": true,
+    "noEmit": false,                              /* Do not emit outputs. */
+        "emitDeclarationOnly": true,
     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
      "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
Index: chipper/tsconfig/common-code/tsconfig.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/tsconfig/common-code/tsconfig.json b/chipper/tsconfig/common-code/tsconfig.json
new file mode 100644
--- /dev/null	(date 1710195926341)
+++ b/chipper/tsconfig/common-code/tsconfig.json	(date 1710195926341)
@@ -0,0 +1,124 @@
+{
+  "extends": "../../tsconfig-core.json",
+  // Explicitly list all entry points that we want to type check.
+  // Imported images/mipmaps/sounds are still type checked.
+  // This structure was determined in https://github.com/phetsims/chipper/issues/1245
+  "include": [
+    "../../../axon/js/**/*",
+    "../../../bamboo/js/**/*",
+
+    "../../../brand/adapted-from-phet/js/Brand.ts",
+    "../../../brand/phet-io/js/Brand.ts",
+    "../../../brand/phet/js/Brand.ts",
+    "../../../brand/phet/images/**/*",
+    "../../../brand/phet-io/images/**/*",
+    "../../../brand/adapted-from-phet/images/**/*",
+    "../../../brand/js/**/*",
+
+    "../../../chipper/js/phet-build-script/phet-build-script.ts",
+    "../../../chipper/phet-types.d.ts",
+    "../../../chipper/js/sim-tests/qunitStart.js",
+    "../../../chipper/js/getStringModule.ts",
+    "../../../chipper/js/data/localeInfoModule.js",
+    "../../../chipper/js/chipper.ts",
+    "../../../chipper/js/LocalizedString.ts",
+
+    "../../../dot/js/**/*",
+    "../../../griddle/js/**/*",
+    "../../../joist/js/**/*",
+    "../../../joist/sounds/**/*",
+    "../../../joist/images/**/*",
+    "../../../kite/js/**/*",
+    "../../../mobius/js/**/*",
+    "../../../nitroglycerin/js/**/*",
+
+    "../../../perennial/js/scripts/collate-lint.ts",
+    "../../../perennial-alias/js/scripts/collate-lint.ts",
+
+    "../../../phet-core/js/**/*",
+
+    "../../../phet-io/js/**/*",
+
+    "../../../phet-io-sim-specific/repos/**/*",
+    "../../../phet-io-sim-specific/js/migration-common/**/*",
+    "../../../phet-io-wrappers/js/**/*",
+    "../../../phet-io-wrappers/common/**/*",
+    "../../../phet-lib/common/**/*",
+    "../../../phetcommon/js/**/*",
+    "../../../quake/cordova-plugin-native-vibration/types/index.d.ts",
+    "../../../scenery/js/**/*",
+    "../../../scenery-phet/js/**/*",
+    "../../../scenery-phet/images/**/*",
+    "../../../scenery-phet/sounds/**/*",
+    "../../../scenery-phet/mipmaps/**/*",
+    "../../../sherpa/js/**/*",
+    "../../../sherpa/lib/lodash-4.17.4.min.js",
+    "../../../sherpa/lib/game-up-camera-1.0.0.js",
+    "../../../studio/js/**/*",
+    "../../../sun/js/**/*",
+    "../../../tambo/js/**/*",
+    "../../../tambo/images/**/*",
+    "../../../tambo/sounds/**/*",
+    "../../../tappi/js/**/*",
+    "../../../tandem/js/**/*",
+    "../../../tangible/js/**/*",
+    "../../../twixt/js/**/*",
+    "../../../utterance-queue/js/**/*",
+    "../../../vegas/js/**/*",
+    "../../../vegas/images/**/*",
+    "../../../vegas/sounds/**/*",
+
+    "../../../sherpa/lib/big-6.2.1.mjs",
+    "../../../sherpa/lib/pako-2.0.3.min.js",
+    "../../../sherpa/lib/peggy-3.0.2.js",
+//    "../../../perennial/js/common/ReleaseBranch.js",
+//    "../../../perennial/js/common/simPhetioMetadata.js",
+    "../../../sherpa/lib/himalaya-1.1.0.js",
+    "../../../chipper/js/LocalizedStringProperty.ts",
+//    "../../../perennial/js/common/loadJSON.js",
+//    "../../../perennial/js/common/execute.js",
+//    "../../../perennial/js/common/gitCheckoutDirectory.js",
+//    "../../../perennial/js/common/npmCommand.js",
+//    "../../../perennial/js/common/npmUpdateDirectory.js",
+//    "../../../perennial/js/common/getDependencies.js",
+//    "../../../perennial/js/common/gitCheckout.js",
+//    "../../../perennial/js/common/npmUpdate.js",
+//    "../../../perennial/js/common/gitDoesCommitExist.js",
+//    "../../../perennial/js/common/gitFetch.js",
+//    "../../../perennial/js/common/gitFetchCheckout.js",
+//    "../../../perennial/js/common/gitPullDirectory.js",
+//    "../../../perennial/js/common/checkoutDependencies.js",
+//    "../../../perennial/js/common/gitPull.js",
+//    "../../../perennial/js/common/getRepoList.js",
+//    "../../../perennial/js/common/getBranch.js",
+//    "../../../perennial/js/common/getGitFile.js",
+//    "../../../perennial/js/common/createLocalBranchFromRemote.js",
+//    "../../../perennial/js/common/getFileAtBranch.js",
+//    "../../../perennial/js/common/SimVersion.js",
+//    "../../../perennial/js/common/gitCloneDirectory.js",
+//    "../../../perennial/js/common/sleep.js",
+//    "../../../perennial/js/common/browserPageLoad.js",
+//    "../../../perennial/js/common/buildLocal.js",
+//    "../../../perennial/js/common/buildServerRequest.js",
+//    "../../../perennial/js/common/ChipperVersion.js",
+//    "../../../perennial/js/common/checkoutMain.js",
+//    "../../../perennial/js/common/checkoutTarget.js",
+//    "../../../perennial/js/common/createDirectory.js",
+//    "../../../perennial/js/common/getActiveSims.js",
+//    "../../../perennial/js/common/getBranchDependencies.js",
+//    "../../../perennial/js/common/getBranches.js",
+//    "../../../perennial/js/common/getBuildArguments.js",
+//    "../../../perennial/js/common/getBranchMap.js",
+//    "../../../perennial/js/common/getBranchVersion.js",
+//    "../../../perennial/js/common/getRepoVersion.js",
+//    "../../../perennial/js/common/gitCloneOrFetchDirectory.js",
+//    "../../../perennial/js/common/gitFirstDivergingCommit.js",
+//    "../../../perennial/js/common/gitIsAncestor.js",
+//    "../../../perennial/js/common/gitRevParse.js",
+//    "../../../perennial/js/common/gitTimestamp.js",
+//    "../../../perennial/js/common/gruntCommand.js",
+//    "../../../perennial/js/common/puppeteerLoad.js",
+//    "../../../perennial/js/common/simMetadata.js",
+//    "../../../perennial/js/common/withServer.js"
+  ]
+}
\ No newline at end of file
Index: phet-io/js/scripts/print-public-sim-versions.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-io/js/scripts/print-public-sim-versions.js b/phet-io/js/scripts/print-public-sim-versions.js
--- a/phet-io/js/scripts/print-public-sim-versions.js	(revision 3e59e1effe8d1646cf92ca39835487aa1a01098f)
+++ b/phet-io/js/scripts/print-public-sim-versions.js	(date 1710195943024)
@@ -1,57 +1,57 @@
-// Copyright 2023, University of Colorado Boulder
-// This PhET-iO file requires a license
-// USE WITHOUT A LICENSE AGREEMENT IS STRICTLY PROHIBITED.
-// For licensing, please contact phethelp@colorado.edu
-
-/**
- * Print the release branches that have been set to `allowPublicAccess`. This will provide public access to the entire
- * publication.
- *
- * usage:
- * cd phet-io/
- * node js/scripts/print-public-sim-versions.js
- *
- * @author Michael Kauzmann (PhET Interactive Simulations)
- *
- */
-
-const simPhetioMetadata = require( '../../../perennial/js/common/simPhetioMetadata' );
-const ReleaseBranch = require( '../../../perennial/js/common/ReleaseBranch' );
-const gitCheckoutDirectory = require( '../../../perennial/js/common/gitCheckoutDirectory' );
-const loadJSON = require( '../../../perennial/js/common/loadJSON' );
-const _ = require( '../../../perennial/node_modules/lodash' );
-
-( async () => {
-
-  const publicReleaseBranches = [];
-
-  let phetioBranches = ( await simPhetioMetadata() ).filter( simData => simData.active && simData.latest ).map( simData => {
-    let branch = `${simData.versionMajor}.${simData.versionMinor}`;
-    if ( simData.versionSuffix.length ) {
-      branch += `-${simData.versionSuffix}`; // additional dash required
-    }
-    return new ReleaseBranch( simData.name, branch, [ 'phet-io' ], true );
-  } );
-
-  // It looks nicer when they are handled in alphabetical order
-  phetioBranches = _.sortBy( phetioBranches, releaseBranch => releaseBranch.repo );
-
-  for ( const releaseBranch of phetioBranches ) {
-    const repo = releaseBranch.repo;
-    console.log( repo, releaseBranch.branch );
-
-    const repoPath = `../${repo}`;
-    await gitCheckoutDirectory( releaseBranch.branch, repoPath );
-
-    const packageObject = await loadJSON( `${repoPath}/package.json` );
-
-    if ( _.hasIn( packageObject, 'phet["phet-io"].allowPublicAccess' ) && packageObject.phet[ 'phet-io' ].allowPublicAccess ) {
-      publicReleaseBranches.push( `${releaseBranch.repo} - ${releaseBranch.branch}` );
-    }
-
-    await gitCheckoutDirectory( 'main', repoPath );
-  }
-
-  console.log( '\n\nPublic sim versions:' );
-  console.log( publicReleaseBranches.join( '\n' ) );
-} )();
\ No newline at end of file
+// // Copyright 2023, University of Colorado Boulder
+// // This PhET-iO file requires a license
+// // USE WITHOUT A LICENSE AGREEMENT IS STRICTLY PROHIBITED.
+// // For licensing, please contact phethelp@colorado.edu
+//
+// /**
+//  * Print the release branches that have been set to `allowPublicAccess`. This will provide public access to the entire
+//  * publication.
+//  *
+//  * usage:
+//  * cd phet-io/
+//  * node js/scripts/print-public-sim-versions.js
+//  *
+//  * @author Michael Kauzmann (PhET Interactive Simulations)
+//  *
+//  */
+//
+// const simPhetioMetadata = require( '../../../perennial/js/common/simPhetioMetadata' );
+// const ReleaseBranch = require( '../../../perennial/js/common/ReleaseBranch' );
+// const gitCheckoutDirectory = require( '../../../perennial/js/common/gitCheckoutDirectory' );
+// const loadJSON = require( '../../../perennial/js/common/loadJSON' );
+// const _ = require( '../../../perennial/node_modules/lodash' );
+//
+// ( async () => {
+//
+//   const publicReleaseBranches = [];
+//
+//   let phetioBranches = ( await simPhetioMetadata() ).filter( simData => simData.active && simData.latest ).map( simData => {
+//     let branch = `${simData.versionMajor}.${simData.versionMinor}`;
+//     if ( simData.versionSuffix.length ) {
+//       branch += `-${simData.versionSuffix}`; // additional dash required
+//     }
+//     return new ReleaseBranch( simData.name, branch, [ 'phet-io' ], true );
+//   } );
+//
+//   // It looks nicer when they are handled in alphabetical order
+//   phetioBranches = _.sortBy( phetioBranches, releaseBranch => releaseBranch.repo );
+//
+//   for ( const releaseBranch of phetioBranches ) {
+//     const repo = releaseBranch.repo;
+//     console.log( repo, releaseBranch.branch );
+//
+//     const repoPath = `../${repo}`;
+//     await gitCheckoutDirectory( releaseBranch.branch, repoPath );
+//
+//     const packageObject = await loadJSON( `${repoPath}/package.json` );
+//
+//     if ( _.hasIn( packageObject, 'phet["phet-io"].allowPublicAccess' ) && packageObject.phet[ 'phet-io' ].allowPublicAccess ) {
+//       publicReleaseBranches.push( `${releaseBranch.repo} - ${releaseBranch.branch}` );
+//     }
+//
+//     await gitCheckoutDirectory( 'main', repoPath );
+//   }
+//
+//   console.log( '\n\nPublic sim versions:' );
+//   console.log( publicReleaseBranches.join( '\n' ) );
+// } )();
\ No newline at end of file

It goes from 48 errors to 10541 errors when it crosses the threshold and starts checking for properties of exported class expressions not being private or protected:

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'speakContent' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateActiveDescendantAssociationsInPeers' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateMaxDimension' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateSelfBounds' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../tandem/js/Tandem.ts:490:26 - error TS4094: Property 'dispose' of exported class expression may not be private or protected.

490   public static readonly ROOT = new Tandem.RootTandem( null, _.camelCase( packageJSON.name ) );
                             ~~~~

../../../tandem/js/Tandem.ts:490:26 - error TS4094: Property 'isDisposed' of exported class expression may not be private or protected.

490   public static readonly ROOT = new Tandem.RootTandem( null, _.camelCase( packageJSON.name ) );
                             ~~~~

../../../tandem/js/Tandem.ts:490:26 - error TS4094: Property 'removeChild' of exported class expression may not be private or protected.

490   public static readonly ROOT = new Tandem.RootTandem( null, _.camelCase( packageJSON.name ) );
                             ~~~~


Found 10541 errors.

Would abandoning mixins be one way forward here?

See notes in https://github.com/TerriaJS/terriajs/issues/5866#issuecomment-1078585855

typeof emits were decided against in https://github.com/microsoft/TypeScript/issues/41824#issue-757463042

@samreid
Copy link
Member Author

samreid commented Mar 13, 2024

Experimenting with mixins, I created this sample project:

type Constructor<T = object, K extends any[] = any[]> = new ( ...args: K ) => T;

const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types

  return class extends type {

    protected readonly layoutBounds = null;

    /**
     * Hide the popup. If you create a new popup next time you show(), be sure to dispose this popup instead.
     */
    public hide(): void {
    }

    protected show(): void {

    }
  };
};
export default Popupable;
/**
 * Shared defaults for tsconfig files.
 * @author Sam Reid (PhET Interactive Simulations)
 */
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Basic Options */
    "incremental": true,                         /* Enable incremental compilation */
    "target": "ES2020",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
    "module": "ES2020",                          /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "allowJs": true,                             /* Allow javascript files to be compiled. */
    "checkJs": false,                            /* Report errors in .js files. */
    "declaration": false,                         /* Generates corresponding '.d.ts' file. */
    "sourceMap": false,                           /* Generates corresponding '.map' file. */
    "outDir": "./outdir",     /* Redirect output structure to the directory. */
    "rootDir": "../",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "composite": false,                             /* Enable project compilation */
//    "noEmit": true,                              /* Do not emit outputs. */
//    "emitDeclarationOnly": true,
    "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    "strict": true,                              /* Enable all strict type-checking options. */
    "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */
    "noImplicitOverride": true,                  /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
    "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  },
  "include": [
    "js/**/*.ts"
  ]
}

This type checks correctly from the command line:

~/phet/root/tinyproj$ tsc -b
~/phet/root/tinyproj$ 

However, changing the following (necessary for a project reference):

  • declaration => true
  • composite => true

Gives these type checking errors:

~/phet/root/tinyproj$ tsc -b
js/Popupable.ts:3:7 - error TS4094: Property 'layoutBounds' of exported class expression may not be private or protected.

3 const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
        ~~~~~~~~~

js/Popupable.ts:3:7 - error TS4094: Property 'show' of exported class expression may not be private or protected.

3 const Popupable = <SuperType extends Constructor<Node>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types
        ~~~~~~~~~


Found 2 errors.

~/phet/root/tinyproj$ 

This means that we cannot have the following two things at the same time:

  • Project References
  • Mixins with private or protected members

Note that @pixelzoom said in #1267 (comment)

Therefore we have these options:

1. Convert mixin members to be public

Changing mixin members to be public works around this problem. However, note that @pixelzoom said in #1267 (comment)

Excellent, glad we can add accessibility modifiers to mixins.

So it would be unfortunate if we had to make everything in mixins public.

2. Abandon project references

We could abandon project references, and continue using the "monolithic" strategy for type checking a full stack at once, which avoids emitting mixin private/protected members. We could look into other ways to conserve memory. One way could be to make change the lint configurations to be "per simulation and its dependencies" and get rid of the "everything" lint configuration. This may be the easiest thing to investigate next (lowest up-front cost). But aside from reducing the memory footprint, there could be other advantages of using project references, such as speed/modularity. So it would be unfortunate to rule out memory and time-saving type checking/linting because we cannot use project references. It could also be unfortunate to not be able to type check the entire project with one tsc invocation.

3. Abandon mixins

It seems we have around 15 mixins defined across the project. Mixins that only mix into one thing could be converted to a class. For instance, at the moment, Paintable only mixes like Paintable(Node), so it could be converted to PaintableNode extends Node. This should not be done lightly since other developers may have plans for mixing things into other types in the future. Other cases like Voicing(VBox) could be converted to inheritance + composition VoicingNode extends Node{ this.addChild(new VBox())}. There are reasons other than this to abandon mixins. For instance, WebStorm/IntelliJ cannot currently autocomplete mixin methods:

image

However, a lot of work went into setting up mixins the way they are and it would be a considerable development effort to convert to an alternate paradigm.

4. Wild card

Maybe someone can think of another workaround or alternative to the ideas above. For instance, I haven't investigated what happens if you put a ts-ignore on those errors (I suspect they would not be emitted). But maybe one hack could be to ts-ignore the errors and export a type declaration that does the right thing (but type aliases cannot have protected or private members either). I also briefly experimented with isolatedModules: false and saw similar problems. Anyways, just leaving a placeholder for "something else" in further brainstorming.

@samreid
Copy link
Member Author

samreid commented Mar 13, 2024

I'm also somewhat confused about the scope of the exported class expressions rule. For instance, some of the 10541 errors in #1356 (comment) are like:

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateSelfBounds' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

Note that updateSelfBounds is not declared in the mixin. But when I make all of the updateSelfBounds public like so:

Subject: [PATCH] Add PDLStopwatchNode.options.isIcon, see https://github.com/phetsims/projectile-data-lab/issues/248
---
Index: js/nodes/Node.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/nodes/Node.ts b/js/nodes/Node.ts
--- a/js/nodes/Node.ts	(revision 4d9eaff95b6438b36a615a19beda51f5adf2afb8)
+++ b/js/nodes/Node.ts	(date 1710302351140)
@@ -1760,7 +1760,7 @@
    *
    * @returns - Whether the self bounds changed.
    */
-  protected updateSelfBounds(): boolean {
+  public updateSelfBounds(): boolean {
     // The Node implementation (un-overridden) will never change the self bounds (always NOTHING).
     assert && assert( this.selfBoundsProperty._value.equals( Bounds2.NOTHING ) );
     return false;
Index: js/nodes/Path.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/nodes/Path.ts b/js/nodes/Path.ts
--- a/js/nodes/Path.ts	(revision 4d9eaff95b6438b36a615a19beda51f5adf2afb8)
+++ b/js/nodes/Path.ts	(date 1710302351152)
@@ -332,7 +332,7 @@
    *
    * @returns - Whether the self bounds changed.
    */
-  protected override updateSelfBounds(): boolean {
+  public override updateSelfBounds(): boolean {
     const selfBounds = this.hasShape() ? this.computeShapeBounds() : Bounds2.NOTHING;
     const changed = !selfBounds.equals( this.selfBoundsProperty._value );
     if ( changed ) {
Index: js/nodes/Text.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/nodes/Text.ts b/js/nodes/Text.ts
--- a/js/nodes/Text.ts	(revision 4d9eaff95b6438b36a615a19beda51f5adf2afb8)
+++ b/js/nodes/Text.ts	(date 1710302351147)
@@ -360,7 +360,7 @@
    *
    * @returns - Whether the self bounds changed.
    */
-  protected override updateSelfBounds(): boolean {
+  public override updateSelfBounds(): boolean {
     // TODO: don't create another Bounds2 object just for this! https://github.com/phetsims/scenery/issues/1581
     let selfBounds;
 

The number of errors goes from 10541 errors to 10477 errors.

@samreid
Copy link
Member Author

samreid commented Mar 13, 2024

Please also note the above is not just a problem with mixins, but also a problem with any exported class expression. For instance, Tandem.ts defines this class expression:

  private static readonly RootTandem = class RootTandem extends Tandem {

    /**
     * RootTandems only accept specifically named children.
     */
    public override createTandem( name: string, options?: TandemOptions ): Tandem {
      if ( Tandem.VALIDATION ) {
        const allowedOnRoot = name === window.phetio.PhetioIDUtils.GLOBAL_COMPONENT_NAME ||
                              name === REQUIRED_TANDEM_NAME ||
                              name === OPTIONAL_TANDEM_NAME ||
                              name === TEST_TANDEM_NAME ||
                              name === window.phetio.PhetioIDUtils.GENERAL_COMPONENT_NAME ||
                              _.endsWith( name, Tandem.SCREEN_TANDEM_NAME_SUFFIX );
        assert && assert( allowedOnRoot, `tandem name not allowed on root: "${name}"; perhaps try putting it under general or global` );
      }

      return super.createTandem( name, options );
    }
  };

Since it has protected/private members, it fails this type checking rule and cannot be emitted for a d.ts file.

I do not know how much of our project has class expressions related to mixins vs other class expressions. Searching = class yields this result and a few more. For instance: EventTimer.ts has public static readonly PoissonEventModel = class PoissonEventModel {

@samreid
Copy link
Member Author

samreid commented Mar 13, 2024

I wrote in slack:

Marla indicated #1356 will be priorized in coming iterations and that I will likely be on the subteam. In order to understand the problem better, I ran an experiment in #1356 (comment) and it looks like class expressions with protected/private members are not compatible with typescript project references. (Does this sound accurate to you?) We use class expressions in a few ways across our project, but they are the foundation for our mixin pattern. So I wanted to ask Jesse, Michael, Chris and Jonathan, should this issue be about adjusting the way we do mixins (for instance: making everything public, or converting from mixins to inheritance + composition), or should the issue treat mixins as a given and look for other ways to reduce the memory footprint (ways other than typescript project references). Having a brief conversation about this now could inform who should be involved on that subteam.

@samreid
Copy link
Member Author

samreid commented Mar 13, 2024

I was surprised to see that this type checked OK:

type Constructor<T = object, K extends any[] = any[]> = new ( ...args: K ) => T;

const Popupable = <SuperType extends Constructor<any>>( type: SuperType, optionsArgPosition: number ) => { // eslint-disable-line @typescript-eslint/explicit-module-boundary-types

  return class extends type {

    public readonly layoutBounds = null;

    /**
     * Hide the popup. If you create a new popup next time you show(), be sure to dispose this popup instead.
     */
    public hide(): void {
    }

    public show(): void {

    }
  };
};
export default Popupable;

class ParentWindow {
  protected getName() {
    return 'name';
  }
}

export class MyWindow extends Popupable( ParentWindow, 1 ) {
  public constructor() {
    super();
  }

  private dispose(): void {
    console.log( 'dispose' );
  }
}

@samreid
Copy link
Member Author

samreid commented Mar 14, 2024

I visited all mixins and made everything public (in the mixins). This took the number of type errors from 15,000 down to 8,000. But the remaining errors look like this and I cannot explain it:

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'removeNodeThatIsActiveDescendantThisNode' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'setRendererBitmask' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateActiveDescendantAssociationsInPeers' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateMaxDimension' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~

../../../sun/js/ToggleSwitch.ts:86:22 - error TS4094: Property 'updateSelfBounds' of exported class expression may not be private or protected.

86 export default class ToggleSwitch<T> extends Voicing( Node ) {
                        ~~~~~~~~~~~~


Found 8029 errors.
``

@samreid
Copy link
Member Author

samreid commented Mar 14, 2024

Here is a working strategy that specifies the tsconfig file in the repo's package.json:

Subject: [PATCH] Remove unused css, see https://github.com/phetsims/projectile-data-lab/issues/233
---
Index: chipper/eslint/.eslintrc.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/chipper/eslint/.eslintrc.js b/chipper/eslint/.eslintrc.js
--- a/chipper/eslint/.eslintrc.js	(revision 49365d759571523891e8143e8aa5811c93dbd3db)
+++ b/chipper/eslint/.eslintrc.js	(date 1710381270555)
@@ -37,11 +37,9 @@
       ],
       parser: '@typescript-eslint/parser',
       parserOptions: {
-        sourceType: 'module',
+        sourceType: 'module'
 
-        // Provide a tsconfig so that we can use rules that require type information.
-        // NOTE: Providing this slows down eslint substantially, see https://github.com/phetsims/chipper/issues/1114#issuecomment-1065927717
-        project: [ '../chipper/tsconfig/all/tsconfig.json' ]
+        // Subclasses should specify their own tsconfig here
       },
       plugins: [
         '@typescript-eslint'
Index: projectile-data-lab/package.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/projectile-data-lab/package.json b/projectile-data-lab/package.json
--- a/projectile-data-lab/package.json	(revision 5d387795957446a92d9d439511035cfd0f6d6a51)
+++ b/projectile-data-lab/package.json	(date 1710381358989)
@@ -46,6 +46,9 @@
         "files": [
           "**/*.ts"
         ],
+        "parserOptions": {
+          "project": [ "../projectile-data-lab/tsconfig.json" ]
+        },
         "rules": {
           "@typescript-eslint/ban-ts-comment": [
             "error",

samreid added a commit to phetsims/function-builder-basics that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/scenery that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/ph-scale-basics that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/quantum-measurement that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/perennial that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/perennial that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/models-of-the-hydrogen-atom that referenced this issue Sep 20, 2024
samreid added a commit that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/aqua that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/aqua that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/shred that referenced this issue Sep 20, 2024
samreid added a commit to phetsims/perennial that referenced this issue Sep 20, 2024
@samreid
Copy link
Member Author

samreid commented Sep 20, 2024

TODOs for this issue completed and remaining work will be done in related issues. Closing.

@samreid samreid closed this as completed Sep 20, 2024
marlitas added a commit to phetsims/alpenglow that referenced this issue Sep 23, 2024
marlitas added a commit to phetsims/alpenglow that referenced this issue Sep 23, 2024
samreid pushed a commit to phetsims/perennial that referenced this issue Oct 17, 2024
…hetsims/chipper#1356

Signed-off-by: Michael Kauzmann <michael.kauzmann@colorado.edu>
samreid added a commit to phetsims/perennial that referenced this issue Oct 17, 2024
samreid added a commit to phetsims/perennial that referenced this issue Oct 21, 2024
zepumph pushed a commit to phetsims/perennial that referenced this issue Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants