From c94d02bb75ac9626464f2b27625320e61c800f2c Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 14:23:36 -0800
Subject: [PATCH 01/34] REVERT ME: Dev setup

---
 .eslintignore   |  2 ++
 .gitignore      |  3 +++
 .prettierignore |  2 ++
 yarn.lock       | 68 +++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/.eslintignore b/.eslintignore
index d474a40b..788ec3d5 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -15,6 +15,8 @@
 !.*
 .*/
 .eslintcache
+/.yalc*
+/yalc.lock
 
 # ember-try
 /.node_modules.ember-try/
diff --git a/.gitignore b/.gitignore
index 57f1ade9..06f20ec5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,9 @@
 /npm-debug.log*
 /testem.log
 /yarn-error.log
+/.yalc*
+/yalc.lock
+/.vscode*
 
 # ember-try
 /.node_modules.ember-try/
diff --git a/.prettierignore b/.prettierignore
index 4178fd57..a2502fb6 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -15,6 +15,8 @@
 !.*
 .eslintcache
 .lint-todo/
+/.yalc*
+/yalc.lock
 
 # ember-try
 /.node_modules.ember-try/
diff --git a/yarn.lock b/yarn.lock
index 1c24c17f..3e853631 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1124,7 +1124,21 @@
     ember-cli-version-checker "^5.1.2"
     semver "^7.3.5"
 
-"@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.9.0":
+"@embroider/macros@^1.0.0", "@embroider/macros@^1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.9.0.tgz#0df2a56fdd93f11fddea450b6ca83cc2119b5008"
+  integrity sha512-12ElrRT+mX3aSixGHjHnfsnyoH1hw5nM+P+Ax0ITZdp6TaAvWZ8dENnVHltdnv4ssHiX0EsVEXmqbIIdMN4nLA==
+  dependencies:
+    "@embroider/shared-internals" "1.8.3"
+    assert-never "^1.2.1"
+    babel-import-util "^1.1.0"
+    ember-cli-babel "^7.26.6"
+    find-up "^5.0.0"
+    lodash "^4.17.21"
+    resolve "^1.20.0"
+    semver "^7.3.2"
+
+"@embroider/macros@^1.10.0":
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.10.0.tgz#af3844d5db48f001b85cfb096c76727c72ad6c1e"
   integrity sha512-LMbfQGk/a+f6xtvAv5fq/wf2LRxETnbgSCLUf/z6ebzmuskOUxrke+uP55chF/loWrARi9g6erFQ7RDOUoBMSg==
@@ -1138,6 +1152,20 @@
     resolve "^1.20.0"
     semver "^7.3.2"
 
+"@embroider/shared-internals@1.8.3":
+  version "1.8.3"
+  resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-1.8.3.tgz#52d868dc80016e9fe983552c0e516f437bf9b9f9"
+  integrity sha512-N5Gho6Qk8z5u+mxLCcMYAoQMbN4MmH+z2jXwQHVs859bxuZTxwF6kKtsybDAASCtd2YGxEmzcc1Ja/wM28824w==
+  dependencies:
+    babel-import-util "^1.1.0"
+    ember-rfc176-data "^0.3.17"
+    fs-extra "^9.1.0"
+    js-string-escape "^1.0.1"
+    lodash "^4.17.21"
+    resolve-package-path "^4.0.1"
+    semver "^7.3.5"
+    typescript-memoize "^1.0.1"
+
 "@embroider/shared-internals@2.0.0", "@embroider/shared-internals@^2.0.0":
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.0.0.tgz#d8205ec6944362aeecfbb51143db352430ced316"
@@ -3904,7 +3932,43 @@ ember-angle-bracket-invocation-polyfill@^3.0.2:
     ember-compatibility-helpers "^1.0.2"
     silent-error "^1.1.1"
 
-ember-auto-import@^2.4.1, ember-auto-import@^2.6.0:
+ember-auto-import@^2.4.1:
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.5.0.tgz#627607648e87d154f75cd3f70c435355ef7cced9"
+  integrity sha512-fKERUmpZLn4RJiCwTjS7D5zJxgnbF4E6GiSp1GYh53K96S+5UBs06r7ScDI52rq34z0+qdSrA6qiDJ3i/lWqKg==
+  dependencies:
+    "@babel/core" "^7.16.7"
+    "@babel/plugin-proposal-class-properties" "^7.16.7"
+    "@babel/plugin-proposal-decorators" "^7.16.7"
+    "@babel/preset-env" "^7.16.7"
+    "@embroider/macros" "^1.0.0"
+    "@embroider/shared-internals" "^2.0.0"
+    babel-loader "^8.0.6"
+    babel-plugin-ember-modules-api-polyfill "^3.5.0"
+    babel-plugin-htmlbars-inline-precompile "^5.2.1"
+    babel-plugin-syntax-dynamic-import "^6.18.0"
+    broccoli-debug "^0.6.4"
+    broccoli-funnel "^3.0.8"
+    broccoli-merge-trees "^4.2.0"
+    broccoli-plugin "^4.0.0"
+    broccoli-source "^3.0.0"
+    css-loader "^5.2.0"
+    debug "^4.3.1"
+    fs-extra "^10.0.0"
+    fs-tree-diff "^2.0.0"
+    handlebars "^4.3.1"
+    js-string-escape "^1.0.1"
+    lodash "^4.17.19"
+    mini-css-extract-plugin "^2.5.2"
+    parse5 "^6.0.1"
+    resolve "^1.20.0"
+    resolve-package-path "^4.0.3"
+    semver "^7.3.4"
+    style-loader "^2.0.0"
+    typescript-memoize "^1.0.0-alpha.3"
+    walk-sync "^3.0.0"
+
+ember-auto-import@^2.6.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.0.tgz#c7a2f799c9b700d74648cb02e35cf7bc1b44ac02"
   integrity sha512-xUyypxlaqWvrx2KSseLus0H8K7Dt+sXNCvcxtquT2EmIM6r67NuQUT9woiEMa9UBvqcaX2k9hNLeubDl78saig==

From dbbeb9c9a2d03c36671e2ebf31d78a327eca140a Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 14:54:31 -0800
Subject: [PATCH 02/34] Add ember-cli-typescript

---
 package.json                            |  5 ++-
 tests/dummy/app/config/environment.d.ts | 14 +++++++++
 tsconfig.json                           | 42 +++++++++++++++++++++++++
 types/dummy/index.d.ts                  |  0
 types/global.d.ts                       |  7 +++++
 yarn.lock                               | 18 ++++++++++-
 6 files changed, 84 insertions(+), 2 deletions(-)
 create mode 100644 tests/dummy/app/config/environment.d.ts
 create mode 100644 tsconfig.json
 create mode 100644 types/dummy/index.d.ts
 create mode 100644 types/global.d.ts

diff --git a/package.json b/package.json
index 81366758..943c8b7b 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,9 @@
     "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:types": "tsc --noEmit --project types",
     "test:ember": "ember test",
-    "test:ember-compatibility": "ember try:each"
+    "test:ember-compatibility": "ember try:each",
+    "prepack": "ember ts:precompile",
+    "postpack": "ember ts:clean"
   },
   "dependencies": {
     "broccoli-funnel": "^3.0.8",
@@ -41,6 +43,7 @@
     "ember-auto-import": "^2.6.0",
     "ember-cli-babel": "^7.26.11",
     "ember-cli-test-loader": "^3.0.0",
+    "ember-cli-typescript": "^5.2.1",
     "resolve-package-path": "^4.0.3",
     "silent-error": "^1.1.1",
     "validate-peer-dependencies": "^2.2.0"
diff --git a/tests/dummy/app/config/environment.d.ts b/tests/dummy/app/config/environment.d.ts
new file mode 100644
index 00000000..a8f92b9f
--- /dev/null
+++ b/tests/dummy/app/config/environment.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Type declarations for
+ *    import config from 'my-app/config/environment'
+ */
+declare const config: {
+  environment: string;
+  modulePrefix: string;
+  podModulePrefix: string;
+  locationType: 'history' | 'hash' | 'none' | 'auto';
+  rootURL: string;
+  APP: Record<string, unknown>;
+};
+
+export default config;
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..4259d032
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,42 @@
+{
+  "extends": "@tsconfig/ember/tsconfig.json",
+  "compilerOptions": {
+
+    // The combination of `baseUrl` with `paths` allows Ember's classic package
+    // layout, which is not resolvable with the Node resolution algorithm, to
+    // work with TypeScript.
+    "baseUrl": ".",
+    "paths": {
+      "dummy/tests/*": [
+        "tests/*"
+      ],
+      "dummy/*": [
+        "tests/dummy/app/*",
+        "app/*"
+      ],
+      "ember-qunit": [
+        "addon"
+      ],
+      "ember-qunit/*": [
+        "addon/*"
+      ],
+      "ember-qunit/test-support": [
+        "addon-test-support"
+      ],
+      "ember-qunit/test-support/*": [
+        "addon-test-support/*"
+      ],
+      "*": [
+        "types/*"
+      ]
+    }
+  },
+  "include": [
+    "app/**/*",
+    "addon/**/*",
+    "tests/**/*",
+    "types/**/*",
+    "test-support/**/*",
+    "addon-test-support/**/*"
+  ]
+}
diff --git a/types/dummy/index.d.ts b/types/dummy/index.d.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/types/global.d.ts b/types/global.d.ts
new file mode 100644
index 00000000..a9d80774
--- /dev/null
+++ b/types/global.d.ts
@@ -0,0 +1,7 @@
+// Types for compiled templates
+declare module 'ember-qunit/templates/*' {
+  import { TemplateFactory } from 'ember-cli-htmlbars';
+
+  const tmpl: TemplateFactory;
+  export default tmpl;
+}
diff --git a/yarn.lock b/yarn.lock
index 3e853631..23feeecf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2062,7 +2062,7 @@ ansi-styles@^6.1.0:
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
   integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
 
-ansi-to-html@^0.6.6:
+ansi-to-html@^0.6.15, ansi-to-html@^0.6.6:
   version "0.6.15"
   resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7"
   integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ==
@@ -4203,6 +4203,22 @@ ember-cli-typescript@^2.0.2:
     stagehand "^1.0.0"
     walk-sync "^1.0.0"
 
+ember-cli-typescript@^5.2.1:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/ember-cli-typescript/-/ember-cli-typescript-5.2.1.tgz#553030f1ce3e8958b8e4fc34909acd1218cb35f2"
+  integrity sha512-qqp5TAIuPHxHiGXJKL+78Euyhy0zSKQMovPh8sJpN/ZBYx0H90pONufHR3anaMcp1snVfx4B+mb9+7ijOik8ZA==
+  dependencies:
+    ansi-to-html "^0.6.15"
+    broccoli-stew "^3.0.0"
+    debug "^4.0.0"
+    execa "^4.0.0"
+    fs-extra "^9.0.1"
+    resolve "^1.5.0"
+    rsvp "^4.8.1"
+    semver "^7.3.2"
+    stagehand "^1.0.0"
+    walk-sync "^2.2.0"
+
 ember-cli-version-checker@^2.1.2:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz#47771b731fe0962705e27c8199a9e3825709f3b3"

From 184ddd157a1d58ad8f651a7bc8cc271915a370af Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 14:56:31 -0800
Subject: [PATCH 03/34] Check tsc as lint step

---
 package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/package.json b/package.json
index 943c8b7b..d799260c 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
     "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
+    "lint:ts": "tsc --noEmit",
     "start": "ember serve",
     "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:types": "tsc --noEmit --project types",

From 48958d6fecda625229643bf4a6581e8ec6d6e3c0 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 15:03:16 -0800
Subject: [PATCH 04/34] Configure ts/eslint strictness

---
 .eslintrc.js  |  29 ++++++++++++
 package.json  |   9 ++++
 tsconfig.json |  45 +++++++++----------
 yarn.lock     | 120 ++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 175 insertions(+), 28 deletions(-)

diff --git a/.eslintrc.js b/.eslintrc.js
index 1dd2a810..36102a1c 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -45,6 +45,35 @@ module.exports = {
       extends: ['plugin:node/recommended'],
     },
 
+    // ts files
+    {
+      files: ['**/*.ts'],
+      extends: [
+        'eslint:recommended',
+        'plugin:@typescript-eslint/recommended',
+        'plugin:@typescript-eslint/recommended-requiring-type-checking',
+        'plugin:@typescript-eslint/strict',
+      ],
+      parser: '@typescript-eslint/parser',
+      parserOptions: {
+        tsconfigRootDir: __dirname,
+        project: ['./tsconfig.json'],
+      },
+      plugins: ['@typescript-eslint'],
+      rules: {
+        '@typescript-eslint/consistent-type-exports': 'error',
+        '@typescript-eslint/consistent-type-imports': 'error',
+        '@typescript-eslint/explicit-function-return-type': 'error',
+        '@typescript-eslint/method-signature-style': 'error',
+        '@typescript-eslint/no-confusing-void-expression': 'error',
+        '@typescript-eslint/no-redundant-type-constituents': 'error',
+        '@typescript-eslint/prefer-enum-initializers': 'error',
+        '@typescript-eslint/prefer-readonly': 'error',
+        '@typescript-eslint/prefer-readonly-parameter-types': 'error',
+        '@typescript-eslint/promise-function-async': 'error',
+      },
+    },
+
     // test files
     {
       files: ['tests/**/*.js'],
diff --git a/package.json b/package.json
index d799260c..130e2f7e 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,8 @@
     "@tsconfig/ember": "^2.0.0",
     "@types/qunit": "^2.19.4",
     "@types/rsvp": "^4.0.4",
+    "@typescript-eslint/eslint-plugin": "^5.45.1",
+    "@typescript-eslint/parser": "^5.45.1",
     "ember-angle-bracket-invocation-polyfill": "^3.0.2",
     "ember-cli": "~4.10.0",
     "ember-cli-dependency-checker": "^3.3.1",
@@ -131,5 +133,12 @@
   "volta": {
     "node": "14.19.1",
     "yarn": "1.22.18"
+  },
+  "typesVersions": {
+    "*": {
+      "*": [
+        "test-support/*"
+      ]
+    }
   }
 }
diff --git a/tsconfig.json b/tsconfig.json
index 4259d032..b01885cf 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,34 +1,18 @@
 {
   "extends": "@tsconfig/ember/tsconfig.json",
   "compilerOptions": {
-
     // The combination of `baseUrl` with `paths` allows Ember's classic package
     // layout, which is not resolvable with the Node resolution algorithm, to
     // work with TypeScript.
     "baseUrl": ".",
     "paths": {
-      "dummy/tests/*": [
-        "tests/*"
-      ],
-      "dummy/*": [
-        "tests/dummy/app/*",
-        "app/*"
-      ],
-      "ember-qunit": [
-        "addon"
-      ],
-      "ember-qunit/*": [
-        "addon/*"
-      ],
-      "ember-qunit/test-support": [
-        "addon-test-support"
-      ],
-      "ember-qunit/test-support/*": [
-        "addon-test-support/*"
-      ],
-      "*": [
-        "types/*"
-      ]
+      "dummy/tests/*": ["tests/*"],
+      "dummy/*": ["tests/dummy/app/*", "app/*"],
+      "ember-qunit": ["addon"],
+      "ember-qunit/*": ["addon/*"],
+      "ember-qunit/test-support": ["addon-test-support"],
+      "ember-qunit/test-support/*": ["addon-test-support/*"],
+      "*": ["types/*"]
     }
   },
   "include": [
@@ -38,5 +22,18 @@
     "types/**/*",
     "test-support/**/*",
     "addon-test-support/**/*"
-  ]
+  ],
+
+  // type checking
+  "strict": true,
+  "allowUnreachableCode": false,
+  "allowUnusedLabels": false,
+  "exactOptionalPropertyTypes": true,
+  "noFallthroughCasesInSwitch": true,
+  "noImplicitOverride": true,
+  "noImplicitReturns": true,
+  "noPropertyAccessFromIndexSignature": true,
+  "noUncheckedIndexedAccess": true,
+  "noUnusedLocals": true,
+  "noUnusedParameters": true
 }
diff --git a/yarn.lock b/yarn.lock
index 23feeecf..c3c8a5d4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1719,6 +1719,11 @@
   resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32"
   integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg==
 
+"@types/semver@^7.3.12":
+  version "7.3.13"
+  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91"
+  integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==
+
 "@types/serve-static@*":
   version "1.15.0"
   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
@@ -1737,6 +1742,89 @@
   resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
   integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
 
+"@typescript-eslint/eslint-plugin@^5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.1.tgz#ee5b51405f6c9ee7e60e4006d68c69450d3b4536"
+  integrity sha512-cOizjPlKEh0bXdFrBLTrI/J6B/QMlhwE9auOov53tgB+qMukH6/h8YAK/qw+QJGct/PTbdh2lytGyipxCcEtAw==
+  dependencies:
+    "@typescript-eslint/scope-manager" "5.45.1"
+    "@typescript-eslint/type-utils" "5.45.1"
+    "@typescript-eslint/utils" "5.45.1"
+    debug "^4.3.4"
+    ignore "^5.2.0"
+    natural-compare-lite "^1.4.0"
+    regexpp "^3.2.0"
+    semver "^7.3.7"
+    tsutils "^3.21.0"
+
+"@typescript-eslint/parser@^5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.1.tgz#6440ec283fa1373a12652d4e2fef4cb6e7b7e8c6"
+  integrity sha512-JQ3Ep8bEOXu16q0ztsatp/iQfDCtvap7sp/DKo7DWltUquj5AfCOpX2zSzJ8YkAVnrQNqQ5R62PBz2UtrfmCkA==
+  dependencies:
+    "@typescript-eslint/scope-manager" "5.45.1"
+    "@typescript-eslint/types" "5.45.1"
+    "@typescript-eslint/typescript-estree" "5.45.1"
+    debug "^4.3.4"
+
+"@typescript-eslint/scope-manager@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.45.1.tgz#5b87d025eec7035d879b99c260f03be5c247883c"
+  integrity sha512-D6fCileR6Iai7E35Eb4Kp+k0iW7F1wxXYrOhX/3dywsOJpJAQ20Fwgcf+P/TDtvQ7zcsWsrJaglaQWDhOMsspQ==
+  dependencies:
+    "@typescript-eslint/types" "5.45.1"
+    "@typescript-eslint/visitor-keys" "5.45.1"
+
+"@typescript-eslint/type-utils@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.1.tgz#cb7d300c3c95802cea9f87c7f8be363cf8f8538c"
+  integrity sha512-aosxFa+0CoYgYEl3aptLe1svP910DJq68nwEJzyQcrtRhC4BN0tJAvZGAe+D0tzjJmFXe+h4leSsiZhwBa2vrA==
+  dependencies:
+    "@typescript-eslint/typescript-estree" "5.45.1"
+    "@typescript-eslint/utils" "5.45.1"
+    debug "^4.3.4"
+    tsutils "^3.21.0"
+
+"@typescript-eslint/types@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.1.tgz#8e1883041cee23f1bb7e1343b0139f97f6a17c14"
+  integrity sha512-HEW3U0E5dLjUT+nk7b4lLbOherS1U4ap+b9pfu2oGsW3oPu7genRaY9dDv3nMczC1rbnRY2W/D7SN05wYoGImg==
+
+"@typescript-eslint/typescript-estree@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz#b3dc37f0c4f0fe73e09917fc735e6f96eabf9ba4"
+  integrity sha512-76NZpmpCzWVrrb0XmYEpbwOz/FENBi+5W7ipVXAsG3OoFrQKJMiaqsBMbvGRyLtPotGqUfcY7Ur8j0dksDJDng==
+  dependencies:
+    "@typescript-eslint/types" "5.45.1"
+    "@typescript-eslint/visitor-keys" "5.45.1"
+    debug "^4.3.4"
+    globby "^11.1.0"
+    is-glob "^4.0.3"
+    semver "^7.3.7"
+    tsutils "^3.21.0"
+
+"@typescript-eslint/utils@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.1.tgz#39610c98bde82c4792f2a858b29b7d0053448be2"
+  integrity sha512-rlbC5VZz68+yjAzQBc4I7KDYVzWG2X/OrqoZrMahYq3u8FFtmQYc+9rovo/7wlJH5kugJ+jQXV5pJMnofGmPRw==
+  dependencies:
+    "@types/json-schema" "^7.0.9"
+    "@types/semver" "^7.3.12"
+    "@typescript-eslint/scope-manager" "5.45.1"
+    "@typescript-eslint/types" "5.45.1"
+    "@typescript-eslint/typescript-estree" "5.45.1"
+    eslint-scope "^5.1.1"
+    eslint-utils "^3.0.0"
+    semver "^7.3.7"
+
+"@typescript-eslint/visitor-keys@5.45.1":
+  version "5.45.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz#204428430ad6a830d24c5ac87c71366a1cfe1948"
+  integrity sha512-cy9ln+6rmthYWjH9fmx+5FU/JDpjQb586++x2FZlveq7GdGuLLW9a2Jcst2TGekH82bXpfmRNSwP9tyEs6RjvQ==
+  dependencies:
+    "@typescript-eslint/types" "5.45.1"
+    eslint-visitor-keys "^3.3.0"
+
 "@webassemblyjs/ast@1.11.1":
   version "1.11.1"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
@@ -3699,7 +3787,7 @@ debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.
   dependencies:
     ms "2.0.0"
 
-debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2:
+debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
   integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -4773,7 +4861,7 @@ eslint-plugin-prettier@^4.2.1:
   dependencies:
     prettier-linter-helpers "^1.0.0"
 
-eslint-scope@5.1.1:
+eslint-scope@5.1.1, eslint-scope@^5.1.1:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
   integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
@@ -5134,7 +5222,7 @@ fast-diff@^1.1.2:
   resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
   integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
 
-fast-glob@^3.0.3, fast-glob@^3.2.11:
+fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.9:
   version "3.2.12"
   resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
   integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
@@ -5858,6 +5946,18 @@ globby@13.1.2:
     merge2 "^1.4.1"
     slash "^4.0.0"
 
+globby@^11.1.0:
+  version "11.1.0"
+  resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
+  integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
+  dependencies:
+    array-union "^2.1.0"
+    dir-glob "^3.0.1"
+    fast-glob "^3.2.9"
+    ignore "^5.2.0"
+    merge2 "^1.4.1"
+    slash "^3.0.0"
+
 globrex@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
@@ -8077,6 +8177,11 @@ nanomatch@^1.2.9:
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
+natural-compare-lite@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4"
+  integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==
+
 natural-compare@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -10574,7 +10679,7 @@ tree-sync@^2.0.0, tree-sync@^2.1.0:
     quick-temp "^0.1.5"
     walk-sync "^0.3.3"
 
-tslib@^1.9.0:
+tslib@^1.8.1, tslib@^1.9.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@@ -10584,6 +10689,13 @@ tslib@^2.0.1, tslib@^2.1.0:
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
   integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
 
+tsutils@^3.21.0:
+  version "3.21.0"
+  resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
+  integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
+  dependencies:
+    tslib "^1.8.1"
+
 type-check@^0.4.0, type-check@~0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"

From 2ac042f8f5965d0e7e939a87d44a8a4fd024362c Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 15:21:10 -0800
Subject: [PATCH 05/34] Rename adddon-test-support/adapter to TS

---
 addon-test-support/{adapter.js => adapter.ts} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addon-test-support/{adapter.js => adapter.ts} (100%)

diff --git a/addon-test-support/adapter.js b/addon-test-support/adapter.ts
similarity index 100%
rename from addon-test-support/adapter.js
rename to addon-test-support/adapter.ts

From 874ba77213af05707ad5d98d1bf4b416d4ea4f80 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 5 Dec 2022 16:46:58 -0800
Subject: [PATCH 06/34] Fix type checking errors for adapter.ts

---
 .eslintrc.js                     |  2 +-
 addon-test-support/adapter.ts    | 85 +++++++++++++++++++++-----------
 addon-test-support/types/util.ts | 20 ++++++++
 types/global.d.ts                |  2 +-
 4 files changed, 77 insertions(+), 32 deletions(-)
 create mode 100644 addon-test-support/types/util.ts

diff --git a/.eslintrc.js b/.eslintrc.js
index 36102a1c..7a07c074 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -61,6 +61,7 @@ module.exports = {
       },
       plugins: ['@typescript-eslint'],
       rules: {
+        '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
         '@typescript-eslint/consistent-type-exports': 'error',
         '@typescript-eslint/consistent-type-imports': 'error',
         '@typescript-eslint/explicit-function-return-type': 'error',
@@ -69,7 +70,6 @@ module.exports = {
         '@typescript-eslint/no-redundant-type-constituents': 'error',
         '@typescript-eslint/prefer-enum-initializers': 'error',
         '@typescript-eslint/prefer-readonly': 'error',
-        '@typescript-eslint/prefer-readonly-parameter-types': 'error',
         '@typescript-eslint/promise-function-async': 'error',
       },
     },
diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index 7673f392..36f81ed4 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -1,61 +1,84 @@
+// FIXME: Remove
+import 'ember-source/types';
+import 'ember-source/types/preview';
+
+import hasEmberVersion from '@ember/test-helpers/has-ember-version';
 import Ember from 'ember';
+import { isRecord, isTest } from 'ember-qunit/test-support/types/util';
 import * as QUnit from 'qunit';
-import hasEmberVersion from '@ember/test-helpers/has-ember-version';
 
-function unhandledRejectionAssertion(current, error) {
-  let message, source;
+function unhandledRejectionAssertion(current: unknown, error: unknown): void {
+  let message: string;
+  let source: string | undefined;
 
-  if (typeof error === 'object' && error !== null) {
-    message = error.message;
-    source = error.stack;
+  if (
+    isRecord(error) &&
+    'message' in error &&
+    typeof error['message'] === 'string'
+  ) {
+    message = error['message'];
+    source = typeof error['stack'] === 'string' ? error['stack'] : undefined;
   } else if (typeof error === 'string') {
     message = error;
     source = 'unknown source';
   } else {
-    message = 'unhandledRejection occured, but it had no message';
+    message = 'unhandledRejection occurred, but it had no message';
     source = 'unknown source';
   }
 
-  current.assert.pushResult({
-    result: false,
-    actual: false,
-    expected: true,
-    message: message,
-    source: source,
-  });
+  if (isTest(current)) {
+    current.assert?.pushResult({
+      result: false,
+      actual: false,
+      expected: true,
+      message: message,
+      // @ts-expect-error FIXME: Update qunit type https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/docs/callbacks/QUnit.log.md?plain=1#L32
+      source,
+    });
+  }
 }
 
-export function nonTestDoneCallback() {}
+export function nonTestDoneCallback(): void {
+  // no-op
+}
+
+// FIXME: What is Ember.Test.QUnitAdapter?
+interface QUnitAdapter {
+  doneCallbacks: Array<{ test: unknown; done: () => void }>;
+  qunit: QUnit;
+}
 
+// @ts-expect-error FIXME `extend` does not exist on Adapter
+// eslint-disable-next-line @typescript-eslint/no-unsafe-call
 let Adapter = Ember.Test.Adapter.extend({
-  init() {
+  init(this: QUnitAdapter) {
     this.doneCallbacks = [];
-    this.qunit = this.qunit || QUnit;
+    this.qunit ??= QUnit;
   },
 
-  asyncStart() {
-    let currentTest = this.qunit.config.current;
-    let done =
-      currentTest && currentTest.assert
+  asyncStart(this: QUnitAdapter) {
+    const currentTest: unknown = this.qunit.config.current;
+    const done =
+      isTest(currentTest) && currentTest.assert
         ? currentTest.assert.async()
         : nonTestDoneCallback;
     this.doneCallbacks.push({ test: currentTest, done });
   },
 
-  asyncEnd() {
-    let currentTest = this.qunit.config.current;
+  asyncEnd(this: QUnitAdapter) {
+    const currentCallback = this.doneCallbacks.pop();
 
-    if (this.doneCallbacks.length === 0) {
+    if (!currentCallback) {
       throw new Error(
         'Adapter asyncEnd called when no async was expected. Please create an issue in ember-qunit.'
       );
     }
 
-    let { test, done } = this.doneCallbacks.pop();
+    const { test, done } = currentCallback;
 
     // In future, we should explore fixing this at a different level, specifically
     // addressing the pairing of asyncStart/asyncEnd behavior in a more consistent way.
-    if (test === currentTest) {
+    if (test === this.qunit.config.current) {
       done();
     }
   },
@@ -63,18 +86,20 @@ let Adapter = Ember.Test.Adapter.extend({
   // clobber default implementation of `exception` will be added back for Ember
   // < 2.17 just below...
   exception: null,
-});
+}) as QUnitAdapter;
 
 // Ember 2.17 and higher do not require the test adapter to have an `exception`
 // method When `exception` is not present, the unhandled rejection is
 // automatically re-thrown and will therefore hit QUnit's own global error
 // handler (therefore appropriately causing test failure)
 if (!hasEmberVersion(2, 17)) {
+  // @ts-expect-error FIXME `extend` does not exist on Adapter
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
   Adapter = Adapter.extend({
-    exception(error) {
-      unhandledRejectionAssertion(QUnit.config.current, error);
+    exception(error: unknown) {
+      unhandledRejectionAssertion(QUnit.config.current as unknown, error);
     },
-  });
+  }) as QUnitAdapter;
 }
 
 export default Adapter;
diff --git a/addon-test-support/types/util.ts b/addon-test-support/types/util.ts
new file mode 100644
index 00000000..2f68ce84
--- /dev/null
+++ b/addon-test-support/types/util.ts
@@ -0,0 +1,20 @@
+import type { test } from 'qunit';
+
+/** Checks if the given value is a `Record<string, unknown>`. */
+export function isRecord(value: unknown): value is Record<string, unknown> {
+  return value !== null && typeof value === 'object';
+}
+
+type TestBase = typeof test & { testId: string };
+
+export type SkippedTest = TestBase & { skip: true; assert?: undefined };
+
+export type AssertionTest = TestBase & { assert: Assert };
+
+// FIXME: What is the appropriate Test type? There doesn't appear to be a test type exported from qunit
+// https://github.com/qunitjs/qunit/blob/main/src/test.js#L23
+export type Test = SkippedTest | AssertionTest;
+
+export function isTest(value: unknown): value is Test {
+  return typeof value === 'function' && 'testId' in value;
+}
diff --git a/types/global.d.ts b/types/global.d.ts
index a9d80774..e4e2ef2b 100644
--- a/types/global.d.ts
+++ b/types/global.d.ts
@@ -1,6 +1,6 @@
 // Types for compiled templates
 declare module 'ember-qunit/templates/*' {
-  import { TemplateFactory } from 'ember-cli-htmlbars';
+  import type { TemplateFactory } from 'ember-cli-htmlbars';
 
   const tmpl: TemplateFactory;
   export default tmpl;

From db410ef6a56d25ed261b12904729c134b365787a Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 6 Dec 2022 11:28:08 -0800
Subject: [PATCH 07/34] Rename addon-test-support/test-isoliation-validation to
 TS

---
 ...{test-isolation-validation.js => test-isolation-validation.ts} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addon-test-support/{test-isolation-validation.js => test-isolation-validation.ts} (100%)

diff --git a/addon-test-support/test-isolation-validation.js b/addon-test-support/test-isolation-validation.ts
similarity index 100%
rename from addon-test-support/test-isolation-validation.js
rename to addon-test-support/test-isolation-validation.ts

From 4c66f5c930640cac8352366205d199108ecedf53 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 16:26:24 -0800
Subject: [PATCH 08/34] Fix type checking errors for
 test-isolation-validation.ts

---
 addon-test-support/adapter.ts                 | 32 ++++----
 .../test-isolation-validation.ts              | 60 +++++++++++----
 addon-test-support/types/util.ts              | 77 +++++++++++++++++--
 3 files changed, 133 insertions(+), 36 deletions(-)

diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index 36f81ed4..c4db0fa7 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -2,11 +2,14 @@
 import 'ember-source/types';
 import 'ember-source/types/preview';
 
+import { assert } from '@ember/debug';
 import hasEmberVersion from '@ember/test-helpers/has-ember-version';
 import Ember from 'ember';
-import { isRecord, isTest } from 'ember-qunit/test-support/types/util';
+
 import * as QUnit from 'qunit';
 
+import { isRecord, isTest } from 'ember-qunit/test-support/types/util';
+
 function unhandledRejectionAssertion(current: unknown, error: unknown): void {
   let message: string;
   let source: string | undefined;
@@ -26,16 +29,18 @@ function unhandledRejectionAssertion(current: unknown, error: unknown): void {
     source = 'unknown source';
   }
 
-  if (isTest(current)) {
-    current.assert?.pushResult({
-      result: false,
-      actual: false,
-      expected: true,
-      message: message,
-      // @ts-expect-error FIXME: Update qunit type https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/docs/callbacks/QUnit.log.md?plain=1#L32
-      source,
-    });
-  }
+  assert(
+    'expected current test to have an assert',
+    isTest(current) && 'assert' in current
+  );
+  current.assert.pushResult({
+    result: false,
+    actual: false,
+    expected: true,
+    message: message,
+    // @ts-expect-error FIXME: Update qunit type https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/docs/callbacks/QUnit.log.md?plain=1#L32
+    source,
+  });
 }
 
 export function nonTestDoneCallback(): void {
@@ -59,7 +64,7 @@ let Adapter = Ember.Test.Adapter.extend({
   asyncStart(this: QUnitAdapter) {
     const currentTest: unknown = this.qunit.config.current;
     const done =
-      isTest(currentTest) && currentTest.assert
+      isTest(currentTest) && 'assert' in currentTest
         ? currentTest.assert.async()
         : nonTestDoneCallback;
     this.doneCallbacks.push({ test: currentTest, done });
@@ -97,7 +102,8 @@ if (!hasEmberVersion(2, 17)) {
   // eslint-disable-next-line @typescript-eslint/no-unsafe-call
   Adapter = Adapter.extend({
     exception(error: unknown) {
-      unhandledRejectionAssertion(QUnit.config.current as unknown, error);
+      const currentTest: unknown = QUnit.config.current;
+      unhandledRejectionAssertion(currentTest, error);
     },
   }) as QUnitAdapter;
 }
diff --git a/addon-test-support/test-isolation-validation.ts b/addon-test-support/test-isolation-validation.ts
index f0cebe51..fdf16e30 100644
--- a/addon-test-support/test-isolation-validation.ts
+++ b/addon-test-support/test-isolation-validation.ts
@@ -1,8 +1,19 @@
 /* eslint-disable no-console */
-import * as QUnit from 'qunit';
+
+import { assert } from '@ember/debug';
+// @ts-expect-error FIXME
 import { _cancelTimers as cancelTimers } from '@ember/runloop';
-import { waitUntil, isSettled, getSettledState } from '@ember/test-helpers';
-import { getDebugInfo } from '@ember/test-helpers';
+import {
+  getDebugInfo,
+  getSettledState,
+  isSettled,
+  waitUntil,
+} from '@ember/test-helpers';
+
+import * as QUnit from 'qunit';
+
+import type { Test } from 'ember-qunit/test-support/types/util';
+import { isTest } from 'ember-qunit/test-support/types/util';
 
 /**
  * Detects if a specific test isn't isolated. A test is considered
@@ -18,18 +29,22 @@ import { getDebugInfo } from '@ember/test-helpers';
  * @param {string} testInfo.module The name of the test module
  * @param {string} testInfo.name The test name
  */
-export function detectIfTestNotIsolated(test, message = '') {
+export function detectIfTestNotIsolated(test: Test, message = ''): void {
   if (!isSettled()) {
-    let { debugInfo } = getSettledState();
+    const { debugInfo } = getSettledState();
 
     console.group(`${test.module.name}: ${test.testName}`);
-    debugInfo.toConsole();
+    debugInfo?.toConsole();
     console.groupEnd();
 
-    test.expected++;
+    assert('detectIfTestNotIsolated called on skipped test', !test.skip);
+
+    test.expected = (test.expected ?? 0) + 1;
     test.assert.pushResult({
       result: false,
       message: `${message} \nMore information has been printed to the console. Please use that information to help in debugging.\n\n`,
+      actual: null,
+      expected: null,
     });
   }
 }
@@ -42,20 +57,29 @@ export function detectIfTestNotIsolated(test, message = '') {
  * @function installTestNotIsolatedHook
  * @param {number} delay the delay delay to use when checking for isolation validation
  */
-export function installTestNotIsolatedHook(delay = 50) {
+export function installTestNotIsolatedHook(delay = 50): void {
   if (!getDebugInfo()) {
     return;
   }
 
-  let test = QUnit.config.current;
-  let finish = test.finish;
-  let pushFailure = test.pushFailure;
+  const test: unknown = QUnit.config.current;
+
+  assert(
+    'installTestNotIsolatedHook called with no current test',
+    isTest(test)
+  );
+
+  const finish = test.finish;
+  const pushFailure = test.pushFailure;
 
-  test.pushFailure = function (message) {
-    if (message.indexOf('Test took longer than') === 0) {
+  test.pushFailure = function (
+    ...args: Parameters<typeof pushFailure>
+  ): ReturnType<typeof pushFailure> {
+    const [message] = args;
+    if (message.startsWith('Test took longer than')) {
       detectIfTestNotIsolated(this, message);
     } else {
-      return pushFailure.apply(this, arguments);
+      pushFailure.apply(this, args);
     }
   };
 
@@ -74,8 +98,10 @@ export function installTestNotIsolatedHook(delay = 50) {
   // - 'QUnit.done'
   //    - it detaches the failure from the actual test that failed, making it
   //      more confusing to the end user.
-  test.finish = function () {
-    let doFinish = () => finish.apply(this, arguments);
+  test.finish = function (
+    ...args: Parameters<typeof finish>
+  ): ReturnType<typeof finish> {
+    const doFinish = (): ReturnType<typeof finish> => finish.apply(this, args);
 
     if (isSettled()) {
       return doFinish();
@@ -96,6 +122,8 @@ export function installTestNotIsolatedHook(delay = 50) {
           // canceling timers here isn't perfect, but is as good as we can do
           // to attempt to prevent future tests from failing due to this test's
           // leakage
+          // FIXME
+          // eslint-disable-next-line @typescript-eslint/no-unsafe-call
           cancelTimers();
 
           return doFinish();
diff --git a/addon-test-support/types/util.ts b/addon-test-support/types/util.ts
index 2f68ce84..37287ff5 100644
--- a/addon-test-support/types/util.ts
+++ b/addon-test-support/types/util.ts
@@ -1,20 +1,83 @@
-import type { test } from 'qunit';
-
 /** Checks if the given value is a `Record<string, unknown>`. */
 export function isRecord(value: unknown): value is Record<string, unknown> {
   return value !== null && typeof value === 'object';
 }
 
-type TestBase = typeof test & { testId: string };
+type Hook = (assert: Assert) => void | Promise<void>;
 
-export type SkippedTest = TestBase & { skip: true; assert?: undefined };
+type TestCallback = (assert: Assert) => void | Promise<void>;
 
-export type AssertionTest = TestBase & { assert: Assert };
+// https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/src/core/config.js#L84
+interface Module {
+  name: string;
+  tests: Array<{ name: string; id: string; skip: boolean }>;
+  childModules: Module[]; // FIXME: verify
+  testsRun: number;
+  testsIgnored: number;
+  hooks: {
+    before: Hook[];
+    beforeEach: Hook[];
+    afterEach: Hook[];
+    after: Hook[];
+  };
+  skip?: boolean;
+  ignored?: boolean;
+}
 
 // FIXME: What is the appropriate Test type? There doesn't appear to be a test type exported from qunit
 // https://github.com/qunitjs/qunit/blob/main/src/test.js#L23
-export type Test = SkippedTest | AssertionTest;
+interface TestBase {
+  testId: string;
+  testName: string;
+  expected: null | number;
+  assertions: Array<{ result: boolean; message: string }>;
+  module: Module;
+  steps: unknown[];
+  timeout: undefined;
+  data: unknown;
+  withData: boolean;
+  pauses: Map<string, unknown>;
+  nextPauseId: 1;
+  stackOffset: 0 | 1 | 2 | 3 | 5;
+  errorForStack: Error;
+  testReport: unknown;
+  stack: string;
+  before: () => unknown;
+  run: () => unknown;
+  after: () => void;
+  queueGlobalHook: (hook: unknown, hookName: unknown) => () => unknown;
+  queueHook: (
+    hook: unknown,
+    hookName: unknown,
+    hookOwner: unknown
+  ) => () => unknown;
+  hooks: (handler: unknown) => unknown;
+  finish: () => unknown;
+  preserveTestEnvironment: () => unknown;
+  queue: () => void;
+  pushResult: (resultInfo: unknown) => void;
+  pushFailure: (message: string, source: string, actual: unknown) => void;
+  skip?: true;
+  callback: TestCallback;
+  todo?: boolean;
+  async?: boolean;
+}
+
+export interface AssertionTest extends TestBase {
+  assert: Assert;
+}
+
+export interface SkipTest extends TestBase {
+  skip: true;
+  async: false;
+}
+export interface TodoTest extends TestBase {
+  todo: true;
+  assert: Assert;
+}
+
+export type Test = AssertionTest | SkipTest | TodoTest;
 
 export function isTest(value: unknown): value is Test {
-  return typeof value === 'function' && 'testId' in value;
+  return isRecord(value) && 'testId' in value;
 }

From 2744e02a34026acf4ecc67b55981c5257a2597f4 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 16:27:22 -0800
Subject: [PATCH 09/34] Rename qunit-configuration to TS

---
 .../{qunit-configuration.js => qunit-configuration.ts}            | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addon-test-support/{qunit-configuration.js => qunit-configuration.ts} (100%)

diff --git a/addon-test-support/qunit-configuration.js b/addon-test-support/qunit-configuration.ts
similarity index 100%
rename from addon-test-support/qunit-configuration.js
rename to addon-test-support/qunit-configuration.ts

From a11495e55eb3c861bbfed1d9f2120c41b3cb9184 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 16:30:35 -0800
Subject: [PATCH 10/34] Fix type checking errors for qunit-configuration

---
 addon-test-support/qunit-configuration.ts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/addon-test-support/qunit-configuration.ts b/addon-test-support/qunit-configuration.ts
index 20abdd0c..9c563b95 100644
--- a/addon-test-support/qunit-configuration.ts
+++ b/addon-test-support/qunit-configuration.ts
@@ -5,4 +5,6 @@ QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container' });
 QUnit.config.urlConfig.push({ id: 'nolint', label: 'Disable Linting' });
 QUnit.config.urlConfig.push({ id: 'devmode', label: 'Development mode' });
 
+// @ts-expect-error FIXME qunit types are incorrect
+// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
 QUnit.config.testTimeout = QUnit.urlParams.devmode ? null : 60000; //Default Test Timeout 60 Seconds

From 588c69fe078475d352a68edfa9ce1941f805f86e Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 16:31:39 -0800
Subject: [PATCH 11/34] Rename test-loader to TS

---
 addon-test-support/{test-loader.js => test-loader.ts} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addon-test-support/{test-loader.js => test-loader.ts} (100%)

diff --git a/addon-test-support/test-loader.js b/addon-test-support/test-loader.ts
similarity index 100%
rename from addon-test-support/test-loader.js
rename to addon-test-support/test-loader.ts

From a9f42311dd30b0f766c7dd64aca24d48d858dd73 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 17:00:35 -0800
Subject: [PATCH 12/34] Fix type checking errors on test-loader

---
 addon-test-support/test-loader.ts              | 18 +++++++++++-------
 .../test-support/index.d.ts                    | 17 +++++++++++++++++
 2 files changed, 28 insertions(+), 7 deletions(-)
 create mode 100644 types/ember-cli-test-loader/test-support/index.d.ts

diff --git a/addon-test-support/test-loader.ts b/addon-test-support/test-loader.ts
index 1d111f4e..4eaf9475 100644
--- a/addon-test-support/test-loader.ts
+++ b/addon-test-support/test-loader.ts
@@ -1,26 +1,29 @@
-import * as QUnit from 'qunit';
 import AbstractTestLoader, {
   addModuleExcludeMatcher,
   addModuleIncludeMatcher,
 } from 'ember-cli-test-loader/test-support/index';
+import * as QUnit from 'qunit';
 
 addModuleExcludeMatcher(function (moduleName) {
-  return QUnit.urlParams.nolint && moduleName.match(/\.(jshint|lint-test)$/);
+  // @ts-expect-error FIXME Qunit types argh
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
+  return QUnit.urlParams.nolint && /\.(jshint|lint-test)$/.test(moduleName);
 });
 
 addModuleIncludeMatcher(function (moduleName) {
-  return moduleName.match(/\.jshint$/);
+  return moduleName.endsWith('.jshint');
 });
 
-let moduleLoadFailures = [];
+let moduleLoadFailures: Array<{ stack: unknown }> = [];
 
 QUnit.done(function () {
-  let length = moduleLoadFailures.length;
+  const length = moduleLoadFailures.length;
 
   try {
     if (length === 0) {
       // do nothing
     } else if (length === 1) {
+      // eslint-disable-next-line @typescript-eslint/no-throw-literal
       throw moduleLoadFailures[0];
     } else {
       throw new Error('\n' + moduleLoadFailures.join('\n'));
@@ -32,11 +35,12 @@ QUnit.done(function () {
 });
 
 export class TestLoader extends AbstractTestLoader {
-  moduleLoadFailure(moduleName, error) {
+  moduleLoadFailure(moduleName: string, error: { stack: unknown }): void {
     moduleLoadFailures.push(error);
 
     QUnit.module('TestLoader Failures');
     QUnit.test(moduleName + ': could not be loaded', function () {
+      // eslint-disable-next-line @typescript-eslint/no-throw-literal
       throw error;
     });
   }
@@ -56,6 +60,6 @@ export class TestLoader extends AbstractTestLoader {
 
    @method loadTests
  */
-export function loadTests() {
+export function loadTests(): void {
   new TestLoader().loadModules();
 }
diff --git a/types/ember-cli-test-loader/test-support/index.d.ts b/types/ember-cli-test-loader/test-support/index.d.ts
new file mode 100644
index 00000000..c5ee5ca6
--- /dev/null
+++ b/types/ember-cli-test-loader/test-support/index.d.ts
@@ -0,0 +1,17 @@
+declare module 'ember-cli-test-loader/test-support/index' {
+  export default class TestLoader {
+    static load(): void;
+    shouldLoadModule(moduleName: string): boolean;
+    listModules(): string[];
+    listTestModules(): string[];
+    loadModules(): void;
+    require(moduleName: string): void;
+    unsee(moduleName: string): void;
+    moduleLoadFailure(moduleName: string, error: { stack: unknown }): void;
+  }
+
+  type Matcher = (moduleName: string) => boolean;
+
+  export function addModuleExcludeMatcher(matcher: Matcher): void;
+  export function addModuleIncludeMatcher(matcher: Matcher): void;
+}

From 88f8a5f1aed886d2c4a6def74b3d57119126d6bd Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 17:02:04 -0800
Subject: [PATCH 13/34] Rename index to TS

---
 addon-test-support/{index.js => index.ts} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename addon-test-support/{index.js => index.ts} (100%)

diff --git a/addon-test-support/index.js b/addon-test-support/index.ts
similarity index 100%
rename from addon-test-support/index.js
rename to addon-test-support/index.ts

From 77765f960d1926c944c87712db169cdbbaf33dab Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Fri, 9 Dec 2022 17:45:04 -0800
Subject: [PATCH 14/34] Fix type checking errors on index

---
 addon-test-support/index.ts | 133 ++++++++++++++++++++++++------------
 types/global.d.ts           |   7 --
 2 files changed, 90 insertions(+), 50 deletions(-)

diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index a5258ce4..bc0f6075 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -5,71 +5,97 @@ export { loadTests } from './test-loader';
 
 import './qunit-configuration';
 
+// @ts-expect-error FIXME
 if (typeof Testem !== 'undefined') {
+  // @ts-expect-error FIXME
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
   Testem.hookIntoTestFramework();
 }
 
 import { _backburner } from '@ember/runloop';
-import { resetOnerror, getTestMetadata } from '@ember/test-helpers';
-import { loadTests } from './test-loader';
-import Ember from 'ember';
-import * as QUnit from 'qunit';
-import QUnitAdapter from './adapter';
+import type { BaseContext, TestContext } from '@ember/test-helpers';
 import {
+  getTestMetadata,
+  resetOnerror,
+  setupApplicationContext,
   setupContext,
-  teardownContext,
   setupRenderingContext,
-  setupApplicationContext,
+  teardownContext,
   validateErrorHandler,
 } from '@ember/test-helpers';
+import Ember from 'ember';
+
+import * as QUnit from 'qunit';
+
+import QUnitAdapter from './adapter';
 import { installTestNotIsolatedHook } from './test-isolation-validation';
+import { loadTests } from './test-loader';
 
 let waitForSettled = true;
 
-export function setupTest(hooks, _options) {
-  let options = { waitForSettled, ..._options };
+export type SetupOptions = Parameters<typeof setupContext>[1];
+
+type PrivateSetupOptions = SetupOptions & {
+  waitForSettled?: boolean;
+};
+
+export function setupTest(hooks: GlobalHooks, _options: SetupOptions): void {
+  const options: PrivateSetupOptions = { waitForSettled, ..._options };
 
-  hooks.beforeEach(function (assert) {
-    let testMetadata = getTestMetadata(this);
-    testMetadata.framework = 'qunit';
+  hooks.beforeEach(async function (
+    this: BaseContext,
+    assert: Assert
+  ): Promise<void> {
+    const testMetadata = getTestMetadata(this);
+    testMetadata['framework'] = 'qunit';
 
-    return setupContext(this, options).then(() => {
-      let originalPauseTest = this.pauseTest;
-      this.pauseTest = function QUnit_pauseTest() {
+    await setupContext(this, options);
+
+    // eslint-disable-next-line @typescript-eslint/unbound-method
+    const originalPauseTest = (this as TestContext).pauseTest;
+    (this as TestContext).pauseTest =
+      async function QUnit_pauseTest(): Promise<void> {
         assert.timeout(-1); // prevent the test from timing out
 
         // This is a temporary work around for
         // https://github.com/emberjs/ember-qunit/issues/496 this clears the
         // timeout that would fail the test when it hits the global testTimeout
         // value.
+        // @ts-expect-error FIXME
+        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
         clearTimeout(QUnit.config.timeout);
-        return originalPauseTest.call(this);
+        await originalPauseTest.call(this);
       };
-    });
   });
 
-  hooks.afterEach(function () {
-    return teardownContext(this, options);
+  hooks.afterEach(async function (this: TestContext): Promise<void> {
+    await teardownContext(this, options);
   });
 }
 
-export function setupRenderingTest(hooks, _options) {
-  let options = { waitForSettled, ..._options };
+export function setupRenderingTest(
+  hooks: GlobalHooks,
+  _options: SetupOptions
+): void {
+  const options: PrivateSetupOptions = { waitForSettled, ..._options };
 
   setupTest(hooks, options);
 
-  hooks.beforeEach(function () {
-    return setupRenderingContext(this);
+  hooks.beforeEach(async function (this: TestContext) {
+    await setupRenderingContext(this);
   });
 }
 
-export function setupApplicationTest(hooks, _options) {
-  let options = { waitForSettled, ..._options };
+export function setupApplicationTest(
+  hooks: GlobalHooks,
+  _options: SetupOptions
+): void {
+  const options: PrivateSetupOptions = { waitForSettled, ..._options };
 
   setupTest(hooks, options);
 
-  hooks.beforeEach(function () {
-    return setupApplicationContext(this);
+  hooks.beforeEach(async function (this: TestContext) {
+    await setupApplicationContext(this);
   });
 }
 
@@ -82,19 +108,21 @@ export function setupApplicationTest(hooks, _options) {
 
    @method setupTestContainer
  */
-export function setupTestContainer() {
-  let testContainer = document.getElementById('ember-testing-container');
+export function setupTestContainer(): void {
+  const testContainer = document.getElementById('ember-testing-container');
   if (!testContainer) {
     return;
   }
 
-  let params = QUnit.urlParams;
+  // @ts-expect-error FIXME
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+  const params: Record<string, unknown> = QUnit.urlParams;
 
-  if (params.devmode || params.fullscreencontainer) {
+  if (params['devmode'] || params['fullscreencontainer']) {
     testContainer.classList.add('ember-testing-container-full-screen');
   }
 
-  if (params.nocontainer) {
+  if (params['nocontainer']) {
     testContainer.classList.add('ember-testing-container-hidden');
   }
 }
@@ -103,7 +131,7 @@ export function setupTestContainer() {
    Instruct QUnit to start the tests.
    @method startTests
  */
-export function startTests() {
+export function startTests(): void {
   QUnit.start();
 }
 
@@ -112,8 +140,10 @@ export function startTests() {
 
    @method setupTestAdapter
  */
-export function setupTestAdapter() {
-  Ember.Test.adapter = QUnitAdapter.create();
+export function setupTestAdapter(): void {
+  // @ts-expect-error FIXME
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+  Ember.Test.adapter = QUnitAdapter.create() as typeof QUnitAdapter;
 }
 
 /**
@@ -122,12 +152,14 @@ export function setupTestAdapter() {
   completed. This is done via `QUnit.testStart` and `QUnit.testDone`.
 
  */
-export function setupEmberTesting() {
+export function setupEmberTesting(): void {
   QUnit.testStart(() => {
+    // @ts-expect-error FIXME
     Ember.testing = true;
   });
 
   QUnit.testDone(() => {
+    // @ts-expect-error FIXME
     Ember.testing = false;
   });
 }
@@ -136,11 +168,11 @@ export function setupEmberTesting() {
   Ensures that `Ember.onerror` (if present) is properly configured to re-throw
   errors that occur while `Ember.testing` is `true`.
 */
-export function setupEmberOnerrorValidation() {
+export function setupEmberOnerrorValidation(): void {
   QUnit.module('ember-qunit: Ember.onerror validation', function () {
     QUnit.test('Ember.onerror is functioning properly', function (assert) {
       assert.expect(1);
-      let result = validateErrorHandler();
+      const result = validateErrorHandler();
       assert.ok(
         result.isValid,
         `Ember.onerror handler with invalid testing behavior detected. An Ember.onerror handler _must_ rethrow exceptions when \`Ember.testing\` is \`true\` or the test suite is unreliable. See https://git.io/vbine for more details.`
@@ -149,14 +181,29 @@ export function setupEmberOnerrorValidation() {
   });
 }
 
-export function setupResetOnerror() {
+export function setupResetOnerror(): void {
   QUnit.testDone(resetOnerror);
 }
 
-export function setupTestIsolationValidation(delay) {
+export function setupTestIsolationValidation(delay?: number | undefined): void {
   waitForSettled = false;
   _backburner.DEBUG = true;
-  QUnit.on('testStart', () => installTestNotIsolatedHook(delay));
+  // @ts-expect-error FIXME
+  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
+  QUnit.on('testStart', () => {
+    installTestNotIsolatedHook(delay);
+  });
+}
+
+export interface StartOptions {
+  loadTests?: boolean;
+  setupTestContainer?: boolean;
+  startTests?: boolean;
+  setupTestAdapter?: boolean;
+  setupEmberTesting?: boolean;
+  setupEmberOnerrorValidation?: boolean;
+  setupTestIsolationValidation?: boolean;
+  testIsolationValidationDelay?: number;
 }
 
 /**
@@ -181,7 +228,7 @@ export function setupTestIsolationValidation(delay) {
    time in milliseconds that is allowed _after_ the test is completed for all
    async to have been completed. The default value is 50.
  */
-export function start(options = {}) {
+export function start(options: StartOptions = {}): void {
   if (options.loadTests !== false) {
     loadTests();
   }
@@ -203,7 +250,7 @@ export function start(options = {}) {
   }
 
   if (
-    typeof options.setupTestIsolationValidation !== 'undefined' &&
+    typeof options.testIsolationValidationDelay !== 'undefined' &&
     options.setupTestIsolationValidation !== false
   ) {
     setupTestIsolationValidation(options.testIsolationValidationDelay);
diff --git a/types/global.d.ts b/types/global.d.ts
index e4e2ef2b..e69de29b 100644
--- a/types/global.d.ts
+++ b/types/global.d.ts
@@ -1,7 +0,0 @@
-// Types for compiled templates
-declare module 'ember-qunit/templates/*' {
-  import type { TemplateFactory } from 'ember-cli-htmlbars';
-
-  const tmpl: TemplateFactory;
-  export default tmpl;
-}

From e2517308b617acf4226b02a5199645f2e6e3121d Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 12 Dec 2022 15:10:12 -0800
Subject: [PATCH 15/34] Move ember-source/types imports

---
 addon-test-support/adapter.ts | 4 ----
 types/dummy/index.d.ts        | 2 ++
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index c4db0fa7..c5882168 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -1,7 +1,3 @@
-// FIXME: Remove
-import 'ember-source/types';
-import 'ember-source/types/preview';
-
 import { assert } from '@ember/debug';
 import hasEmberVersion from '@ember/test-helpers/has-ember-version';
 import Ember from 'ember';
diff --git a/types/dummy/index.d.ts b/types/dummy/index.d.ts
index e69de29b..2109bac6 100644
--- a/types/dummy/index.d.ts
+++ b/types/dummy/index.d.ts
@@ -0,0 +1,2 @@
+import 'ember-source/types';
+import 'ember-source/types/preview';

From 434068f157e8fc731939476cc369150cdcc2ea41 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 13:14:54 -0800
Subject: [PATCH 16/34] Merge info from ambient types

---
 addon-test-support/adapter.ts       |   4 +-
 addon-test-support/index.ts         | 315 ++++++++++++++++++++++++----
 docs/legacy.md                      |   2 +
 package.json                        |   3 +-
 types/tests.ts => type-tests/api.ts |   9 +-
 {types => type-tests}/tsconfig.json |   0
 types/index.d.ts                    | 272 ------------------------
 types/local-types.d.ts              |   2 -
 8 files changed, 277 insertions(+), 330 deletions(-)
 rename types/tests.ts => type-tests/api.ts (97%)
 rename {types => type-tests}/tsconfig.json (100%)
 delete mode 100644 types/index.d.ts
 delete mode 100644 types/local-types.d.ts

diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index c5882168..4b421ca9 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -1,4 +1,5 @@
 import { assert } from '@ember/debug';
+import type EmberTestAdapter from '@ember/test/adapter';
 import hasEmberVersion from '@ember/test-helpers/has-ember-version';
 import Ember from 'ember';
 
@@ -43,8 +44,7 @@ export function nonTestDoneCallback(): void {
   // no-op
 }
 
-// FIXME: What is Ember.Test.QUnitAdapter?
-interface QUnitAdapter {
+interface QUnitAdapter extends EmberTestAdapter {
   doneCallbacks: Array<{ test: unknown; done: () => void }>;
   qunit: QUnit;
 }
diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index bc0f6075..5c96e3c1 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -12,6 +12,7 @@ if (typeof Testem !== 'undefined') {
   Testem.hookIntoTestFramework();
 }
 
+import type { Resolver } from '@ember/owner';
 import { _backburner } from '@ember/runloop';
 import type { BaseContext, TestContext } from '@ember/test-helpers';
 import {
@@ -31,16 +32,44 @@ import QUnitAdapter from './adapter';
 import { installTestNotIsolatedHook } from './test-isolation-validation';
 import { loadTests } from './test-loader';
 
+// FIXME: What is this about?
 let waitForSettled = true;
 
-export type SetupOptions = Parameters<typeof setupContext>[1];
+/**
+ * Options for configuring the test runner. Normally, you will not need to
+ * customize this. It is exported primarily so that end user app code can name
+ * it when passing it back to the framework.
+ */
+export interface SetupTestOptions {
+  /**
+   * The resolver to use when instantiating container-managed entities in the test.
+   */
+  resolver?: Resolver | undefined;
+}
 
-type PrivateSetupOptions = SetupOptions & {
+type PrivateSetupOptions = SetupTestOptions & {
+  // FIXME: What is this about?
   waitForSettled?: boolean;
 };
 
-export function setupTest(hooks: GlobalHooks, _options: SetupOptions): void {
-  const options: PrivateSetupOptions = { waitForSettled, ..._options };
+/**
+ * Sets up tests that do not need to render snippets of templates.
+ *
+ * The `setupTest` method is used for all types of tests except for those
+ * that need to render snippets of templates. It is invoked in the callback
+ * scope of a QUnit module (aka "nested module").
+ *
+ * Once invoked, all subsequent hooks.beforeEach and test invocations will
+ * have access to the following:
+ * * this.owner - This exposes the standard "owner API" for the test environment.
+ * * this.set / this.setProperties - Allows setting values on the test context.
+ * * this.get / this.getProperties - Retrieves values from the test context.
+ */
+export function setupTest(
+  hooks: NestedHooks,
+  options?: SetupTestOptions
+): void {
+  const allOptions: PrivateSetupOptions = { waitForSettled, ...options };
 
   hooks.beforeEach(async function (
     this: BaseContext,
@@ -49,7 +78,7 @@ export function setupTest(hooks: GlobalHooks, _options: SetupOptions): void {
     const testMetadata = getTestMetadata(this);
     testMetadata['framework'] = 'qunit';
 
-    await setupContext(this, options);
+    await setupContext(this, allOptions);
 
     // eslint-disable-next-line @typescript-eslint/unbound-method
     const originalPauseTest = (this as TestContext).pauseTest;
@@ -69,30 +98,61 @@ export function setupTest(hooks: GlobalHooks, _options: SetupOptions): void {
   });
 
   hooks.afterEach(async function (this: TestContext): Promise<void> {
-    await teardownContext(this, options);
+    await teardownContext(this, allOptions);
   });
 }
 
+/**
+ * Sets up tests that need to render snippets of templates.
+ *
+ * The setupRenderingTest method is used for tests that need to render
+ * snippets of templates. It is also invoked in the callback scope of a
+ * QUnit module (aka "nested module").
+ *
+ * Once invoked, all subsequent hooks.beforeEach and test invocations will
+ * have access to the following:
+ * * All of the methods / properties listed for `setupTest`
+ * * this.render(...) - Renders the provided template snippet returning a
+ * promise that resolves once rendering has completed
+ * * An importable render function that de-sugars into this.render will be
+ * the default output of blueprints
+ * * this.element - Returns the native DOM element representing the element
+ * that was rendered via this.render
+ * * this.$(...) - When jQuery is present, executes a jQuery selector with
+ * the current this.element as its root
+ */
 export function setupRenderingTest(
-  hooks: GlobalHooks,
-  _options: SetupOptions
+  hooks: NestedHooks,
+  options?: SetupTestOptions
 ): void {
-  const options: PrivateSetupOptions = { waitForSettled, ..._options };
+  const allOptions: PrivateSetupOptions = { waitForSettled, ...options };
 
-  setupTest(hooks, options);
+  setupTest(hooks, allOptions);
 
   hooks.beforeEach(async function (this: TestContext) {
     await setupRenderingContext(this);
   });
 }
 
+/**
+ * Sets up acceptance tests.
+ *
+ * The `setupApplicationTest` function is used for all acceptance tests. It
+ * is invoked in the callback scope of a QUnit module (aka "nested module").
+ *
+ * Once invoked, all subsequent hooks.beforeEach and test invocations will
+ * have access to the following:
+ * * `this.owner` - the owner object that been set on the test context.
+ * * `this.pauseTest` and `this.resumeTest` - allow easy pausing/resuming of tests.
+ * * `this.element` which returns the DOM element representing the application's root element.
+ */
 export function setupApplicationTest(
-  hooks: GlobalHooks,
-  _options: SetupOptions
+  hooks: NestedHooks,
+  options?: SetupTestOptions
 ): void {
-  const options: PrivateSetupOptions = { waitForSettled, ..._options };
+  const allOptions: PrivateSetupOptions = { waitForSettled, ...options };
 
-  setupTest(hooks, options);
+  setupTest(hooks, allOptions);
 
   hooks.beforeEach(async function (this: TestContext) {
     await setupApplicationContext(this);
@@ -195,40 +255,55 @@ export function setupTestIsolationValidation(delay?: number | undefined): void {
   });
 }
 
-export interface StartOptions {
-  loadTests?: boolean;
-  setupTestContainer?: boolean;
-  startTests?: boolean;
-  setupTestAdapter?: boolean;
-  setupEmberTesting?: boolean;
-  setupEmberOnerrorValidation?: boolean;
-  setupTestIsolationValidation?: boolean;
-  testIsolationValidationDelay?: number;
+/** Options to be used for enabling/disabling behaviors */
+export interface QUnitStartOptions {
+  /**
+   * If `false` tests will not be loaded automatically.
+   */
+  loadTests?: boolean | undefined;
+
+  /**
+   * If `false` the test container will not be setup based on `devmode`,
+   * `dockcontainer`, or `nocontainer` URL params.
+   */
+  setupTestContainer?: boolean | undefined;
+
+  /**
+   * If `false` tests will not be automatically started (you must run
+   * `QUnit.start()` to kick them off).
+   */
+  startTests?: boolean | undefined;
+
+  /**
+   * If `false` the default Ember.Test adapter will not be updated.
+   */
+  setupTestAdapter?: boolean | undefined;
+
+  /**
+   * `false` opts out of the default behavior of setting `Ember.testing`
+   * to `true` before all tests and back to `false` after each test will.
+   */
+  setupEmberTesting?: boolean | undefined;
+
+  /**
+   * If `false` validation of `Ember.onerror` will be disabled.
+   */
+  setupEmberOnerrorValidation?: boolean | undefined;
+
+  /**
+   * If `false` test isolation validation will be disabled.
+   */
+  setupTestIsolationValidation?: boolean | undefined;
+
+  /**
+   * When using setupTestIsolationValidation this number represents the maximum
+   * amount of time in milliseconds that is allowed _after_ the test is
+   * completed for all async to have been completed. The default value is 50.
+   */
+  testIsolationValidationDelay?: number | undefined;
 }
 
-/**
-   @method start
-   @param {Object} [options] Options to be used for enabling/disabling behaviors
-   @param {Boolean} [options.loadTests] If `false` tests will not be loaded automatically.
-   @param {Boolean} [options.setupTestContainer] If `false` the test container will not
-   be setup based on `devmode`, `dockcontainer`, or `nocontainer` URL params.
-   @param {Boolean} [options.startTests] If `false` tests will not be automatically started
-   (you must run `QUnit.start()` to kick them off).
-   @param {Boolean} [options.setupTestAdapter] If `false` the default Ember.Test adapter will
-   not be updated.
-   @param {Boolean} [options.setupEmberTesting] `false` opts out of the
-   default behavior of setting `Ember.testing` to `true` before all tests and
-   back to `false` after each test will.
-   @param {Boolean} [options.setupEmberOnerrorValidation] If `false` validation
-   of `Ember.onerror` will be disabled.
-   @param {Boolean} [options.setupTestIsolationValidation] If `false` test isolation validation
-   will be disabled.
-   @param {Number} [options.testIsolationValidationDelay] When using
-   setupTestIsolationValidation this number represents the maximum amount of
-   time in milliseconds that is allowed _after_ the test is completed for all
-   async to have been completed. The default value is 50.
- */
-export function start(options: StartOptions = {}): void {
+export function start(options: QUnitStartOptions = {}): void {
   if (options.loadTests !== false) {
     loadTests();
   }
@@ -262,3 +337,151 @@ export function start(options: StartOptions = {}): void {
 
   setupResetOnerror();
 }
+
+// SAFETY: all of the `TC extends TestContext` generics below are just wildly,
+// impossibly unsafe. QUnit cannot -- ever! -- guarantee that the test context
+// is properly set up in a type-safe way to match this. However, it is the only
+// way to handle setting state in a TS-visible way prior to Ember RFC 0785,
+// which is slooooowly rolling out across the ecosystem in conjunction with the
+// `<template>` feature.
+
+// We need this style to avoid "Subsequent property declarations must have the
+// same type" errors
+/* eslint-disable @typescript-eslint/method-signature-style */
+
+declare global {
+  // NOTE: disables `no-unnecessary-generics` inline because, unfortunately,
+  // the design of Ember's test tooling (and indeed *QUnit's* test system)
+  // requires that we allow users to update the type of the context of the
+  // test. This is indeed strictly *wrong*! However, changing it will require
+  // changing how Ember handles testing. See [the PR][pr] for further details.
+  //
+  // [pr]: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56494
+
+  interface NestedHooks {
+    /**
+     * Runs after the last test. If additional tests are defined after the
+     * module's queue has emptied, it will not run this hook again.
+     */
+    after<TC extends TestContext>(
+      fn: (this: TC, assert: Assert) => void | Promise<void>
+    ): void;
+
+    /**
+     * Runs after each test.
+     */
+    afterEach<TC extends TestContext>(
+      fn: (this: TC, assert: Assert) => void | Promise<void>
+    ): void;
+
+    /**
+     * Runs before the first test.
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    before<TC extends TestContext>(
+      fn: (this: TC, assert: Assert) => void | Promise<void>
+    ): void;
+
+    /**
+     * Runs before each test.
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    beforeEach<TC extends TestContext>(
+      fn: (this: TC, assert: Assert) => void | Promise<void>
+    ): void;
+  }
+
+  interface QUnit {
+    /**
+     * Add a test to run.
+     *
+     * Add a test to run using `QUnit.test()`.
+     *
+     * The `assert` argument to the callback contains all of QUnit's assertion
+     * methods. Use this argument to call your test assertions.
+     *
+     * `QUnit.test()` can automatically handle the asynchronous resolution of a
+     * Promise on your behalf if you return a thenable Promise as the result of
+     * your callback function.
+     *
+     * @param name Title of unit being tested
+     * @param callback Function to close over assertions
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    // provide this guarantee. However, it's also the only way to support TS
+    // in tests in Ember until we move the community over entirely to using
+    // `<template>` and local scope.
+    test<TC extends TestContext>(
+      name: string,
+      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+    ): void;
+
+    /**
+     * Adds a test to exclusively run, preventing all other tests from running.
+     *
+     * Use this method to focus your test suite on a specific test. QUnit.only
+     * will cause any other tests in your suite to be ignored.
+     *
+     * Note, that if more than one QUnit.only is present only the first instance
+     * will run.
+     *
+     * This is an alternative to filtering tests to run in the HTML reporter. It
+     * is especially useful when you use a console reporter or in a codebase
+     * with a large set of long running tests.
+     *
+     * @param name Title of unit being tested
+     * @param callback Function to close over assertions
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    // provide this guarantee. However, it's also the only way to support TS
+    // in tests in Ember until we move the community over entirely to using
+    // `<template>` and local scope.
+    only<TC extends TestContext>(
+      name: string,
+      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+    ): void;
+
+    /**
+     * Use this method to test a unit of code which is still under development (in a “todo” state).
+     * The test will pass as long as one failing assertion is present.
+     *
+     * If all assertions pass, then the test will fail signaling that `QUnit.todo` should
+     * be replaced by `QUnit.test`.
+     *
+     * @param name Title of unit being tested
+     * @param callback Function to close over assertions
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    // provide this guarantee. However, it's also the only way to support TS
+    // in tests in Ember until we move the community over entirely to using
+    // `<template>` and local scope.
+    todo<TC extends TestContext>(
+      name: string,
+      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+    ): void;
+
+    /**
+     * Adds a test like object to be skipped.
+     *
+     * Use this method to replace QUnit.test() instead of commenting out entire
+     * tests.
+     *
+     * This test's prototype will be listed on the suite as a skipped test,
+     * ignoring the callback argument and the respective global and module's
+     * hooks.
+     *
+     * @param name Title of unit being tested
+     * @param callback Function to close over assertions
+     */
+    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
+    // provide this guarantee. However, it's also the only way to support TS
+    // in tests in Ember until we move the community over entirely to using
+    // `<template>` and local scope.
+    skip<TC extends TestContext>(
+      name: string,
+      callback?: (this: TC, assert: Assert) => void | Promise<unknown>
+    ): void;
+  }
+}
+
+/* eslint-enable @typescript-eslint/method-signature-style */
diff --git a/docs/legacy.md b/docs/legacy.md
index e8e12529..13c48db3 100644
--- a/docs/legacy.md
+++ b/docs/legacy.md
@@ -143,6 +143,8 @@ test('It can set its child', function(assert) {
 ## Advanced Usage
 ### Setting the resolver
 
+<!-- FIXME: setResolver is not actually exported from ember-qunit. It comes from @ember/test-helpers -->
+
 ```js
 // if you don't have a custom resolver, do it like this:
 setResolver(Ember.DefaultResolver.create({ namespace: App }));
diff --git a/package.json b/package.json
index 130e2f7e..597fc3d9 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,6 @@
     "doc": "doc",
     "test": "tests"
   },
-  "types": "types/index.d.ts",
   "scripts": {
     "build": "ember build --environment=production",
     "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
@@ -31,7 +30,7 @@
     "lint:ts": "tsc --noEmit",
     "start": "ember serve",
     "test": "npm-run-all --print-name \"lint\" \"test:*\"",
-    "test:types": "tsc --noEmit --project types",
+    "test:types": "tsc --noEmit --project type-tests",
     "test:ember": "ember test",
     "test:ember-compatibility": "ember try:each",
     "prepack": "ember ts:precompile",
diff --git a/types/tests.ts b/type-tests/api.ts
similarity index 97%
rename from types/tests.ts
rename to type-tests/api.ts
index 7846beb8..ccc9385c 100644
--- a/types/tests.ts
+++ b/type-tests/api.ts
@@ -8,18 +8,15 @@ import {
   skip,
   only,
   todo,
-  setResolver,
   setupRenderingTest,
   setupTest,
   SetupTestOptions,
   setupApplicationTest,
 } from 'ember-qunit';
-import { render, RenderingTestContext, TestContext } from '@ember/test-helpers';
+import type { RenderingTestContext, TestContext } from '@ember/test-helpers';
+import { render } from '@ember/test-helpers';
 import EmberResolver from 'ember-resolver';
-import EmberObject from '@ember/object';
-
-// if you don't have a custom resolver, do it like this:
-setResolver(EmberResolver.create());
+import type EmberObject from '@ember/object';
 
 // (modified) tests ported from ember-test-helpers
 module('rendering', function (hooks) {
diff --git a/types/tsconfig.json b/type-tests/tsconfig.json
similarity index 100%
rename from types/tsconfig.json
rename to type-tests/tsconfig.json
diff --git a/types/index.d.ts b/types/index.d.ts
deleted file mode 100644
index d11b83d5..00000000
--- a/types/index.d.ts
+++ /dev/null
@@ -1,272 +0,0 @@
-// Type definitions for ember-qunit 5.0
-// Project: https://github.com/emberjs/ember-qunit#readme
-// Definitions by: Dan Freeman <https://github.com/dfreeman>
-//                 Chris Krycho <https://github.com/chriskrycho>
-//                 James C. Davis <https://github.com/jamescdavis>
-// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
-// Minimum TypeScript Version: 4.4
-
-import EmberTestAdapter from '@ember/test/adapter';
-import { Resolver } from '@ember/owner';
-import { TestContext } from '@ember/test-helpers';
-
-/**
- * Sets a Resolver globally which will be used to look up objects from each test's container.
- */
-export function setResolver(resolver: Resolver): void;
-
-/**
- * Options for configuring the test runner. Normally, you will not need to
- * customize this. It is exported primarily so that end user app code can name
- * it when passing it back to the framework.
- */
-export interface SetupTestOptions {
-  /**
-   * The resolver to use when instantiating container-managed entities in the test.
-   */
-  resolver?: Resolver | undefined;
-}
-
-/**
- * Sets up acceptance tests.
- *
- * The `setupApplicationTest` function is used for all acceptance tests. It
- * is invoked in the callback scope of a QUnit module (aka "nested module").
- *
- * Once invoked, all subsequent hooks.beforeEach and test invocations will
- * have access to the following:
- * * `this.owner` - the owner object that been set on the test context.
- * * `this.pauseTest` and `this.resumeTest` - allow easy pausing/resuming of tests.
- * * `this.element` which returns the DOM element representing the application's root element.
- */
-export function setupApplicationTest(
-  hooks: NestedHooks,
-  options?: SetupTestOptions
-): void;
-
-/**
- * Sets up tests that need to render snippets of templates.
- *
- * The setupRenderingTest method is used for tests that need to render
- * snippets of templates. It is also invoked in the callback scope of a
- * QUnit module (aka "nested module").
- *
- * Once invoked, all subsequent hooks.beforeEach and test invocations will
- * have access to the following:
- * * All of the methods / properties listed for `setupTest`
- * * this.render(...) - Renders the provided template snippet returning a
- * promise that resolves once rendering has completed
- * * An importable render function that de-sugars into this.render will be
- * the default output of blueprints
- * * this.element - Returns the native DOM element representing the element
- * that was rendered via this.render
- * * this.$(...) - When jQuery is present, executes a jQuery selector with
- * the current this.element as its root
- */
-export function setupRenderingTest(
-  hooks: NestedHooks,
-  options?: SetupTestOptions
-): void;
-
-/**
- * Sets up tests that do not need to render snippets of templates.
- *
- * The `setupTest` method is used for all types of tests except for those
- * that need to render snippets of templates. It is invoked in the callback
- * scope of a QUnit module (aka "nested module").
- *
- * Once invoked, all subsequent hooks.beforeEach and test invocations will
- * have access to the following:
- * * this.owner - This exposes the standard "owner API" for the test environment.
- * * this.set / this.setProperties - Allows setting values on the test context.
- * * this.get / this.getProperties - Retrieves values from the test context.
- */
-export function setupTest(hooks: NestedHooks, options?: SetupTestOptions): void;
-
-export class QUnitAdapter extends EmberTestAdapter {}
-
-export { module, test, skip, only, todo } from 'qunit';
-
-interface QUnitStartOptions {
-  /**
-   * If `false` tests will not be loaded automatically.
-   */
-  loadTests?: boolean | undefined;
-
-  /**
-   * If `false` the test container will not be setup based on `devmode`,
-   * `dockcontainer`, or `nocontainer` URL params.
-   */
-  setupTestContainer?: boolean | undefined;
-
-  /**
-   * If `false` tests will not be automatically started (you must run
-   * `QUnit.start()` to kick them off).
-   */
-  startTests?: boolean | undefined;
-
-  /**
-   * If `false` the default Ember.Test adapter will not be updated.
-   */
-  setupTestAdapter?: boolean | undefined;
-
-  /**
-   * `false` opts out of the default behavior of setting `Ember.testing`
-   * to `true` before all tests and back to `false` after each test will.
-   */
-  setupEmberTesting?: boolean | undefined;
-
-  /**
-   * If `false` validation of `Ember.onerror` will be disabled.
-   */
-  setupEmberOnerrorValidation?: boolean | undefined;
-
-  /**
-   * If `false` test isolation validation will be disabled.
-   */
-  setupTestIsolationValidation?: boolean | undefined;
-}
-
-export function start(options?: QUnitStartOptions): void;
-
-// SAFETY: all of the `TC extends TestContext` generics below are just wildly,
-// impossibly unsafe. QUnit cannot -- ever! -- guarantee that the test context
-// is properly set up in a type-safe way to match this. However, it is the only
-// way to handle setting state in a TS-visible way prior to Ember RFC 0785,
-// which is slooooowly rolling out across the ecosystem in conjunction with the
-// `<template>` feature.
-
-declare global {
-  // NOTE: disables `no-unnecessary-generics` inline because, unfortunately,
-  // the design of Ember's test tooling (and indeed *QUnit's* test system)
-  // requires that we allow users to update the type of the context of the
-  // test. This is indeed strictly *wrong*! However, changing it will require
-  // changing how Ember handles testing. See [the PR][pr] for further details.
-  //
-  // [pr]: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56494
-
-  interface NestedHooks {
-    /**
-     * Runs after the last test. If additional tests are defined after the
-     * module's queue has emptied, it will not run this hook again.
-     */
-    after<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
-    ): void;
-
-    /**
-     * Runs after each test.
-     */
-    afterEach<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
-    ): void;
-
-    /**
-     * Runs before the first test.
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    before<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
-    ): void;
-
-    /**
-     * Runs before each test.
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    beforeEach<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
-    ): void;
-  }
-
-  interface QUnit {
-    /**
-     * Add a test to run.
-     *
-     * Add a test to run using `QUnit.test()`.
-     *
-     * The `assert` argument to the callback contains all of QUnit's assertion
-     * methods. Use this argument to call your test assertions.
-     *
-     * `QUnit.test()` can automatically handle the asynchronous resolution of a
-     * Promise on your behalf if you return a thenable Promise as the result of
-     * your callback function.
-     *
-     * @param name Title of unit being tested
-     * @param callback Function to close over assertions
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    // provide this guarantee. However, it's also the only way to support TS
-    // in tests in Ember until we move the community over entirely to using
-    // `<template>` and local scope.
-    test<TC extends TestContext>(
-      name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
-    ): void;
-
-    /**
-     * Adds a test to exclusively run, preventing all other tests from running.
-     *
-     * Use this method to focus your test suite on a specific test. QUnit.only
-     * will cause any other tests in your suite to be ignored.
-     *
-     * Note, that if more than one QUnit.only is present only the first instance
-     * will run.
-     *
-     * This is an alternative to filtering tests to run in the HTML reporter. It
-     * is especially useful when you use a console reporter or in a codebase
-     * with a large set of long running tests.
-     *
-     * @param name Title of unit being tested
-     * @param callback Function to close over assertions
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    // provide this guarantee. However, it's also the only way to support TS
-    // in tests in Ember until we move the community over entirely to using
-    // `<template>` and local scope.
-    only<TC extends TestContext>(
-      name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
-    ): void;
-
-    /**
-     * Use this method to test a unit of code which is still under development (in a “todo” state).
-     * The test will pass as long as one failing assertion is present.
-     *
-     * If all assertions pass, then the test will fail signaling that `QUnit.todo` should
-     * be replaced by `QUnit.test`.
-     *
-     * @param name Title of unit being tested
-     * @param callback Function to close over assertions
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    // provide this guarantee. However, it's also the only way to support TS
-    // in tests in Ember until we move the community over entirely to using
-    // `<template>` and local scope.
-    todo<TC extends TestContext>(
-      name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
-    ): void;
-
-    /**
-     * Adds a test like object to be skipped.
-     *
-     * Use this method to replace QUnit.test() instead of commenting out entire
-     * tests.
-     *
-     * This test's prototype will be listed on the suite as a skipped test,
-     * ignoring the callback argument and the respective global and module's
-     * hooks.
-     *
-     * @param name Title of unit being tested
-     * @param callback Function to close over assertions
-     */
-    // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
-    // provide this guarantee. However, it's also the only way to support TS
-    // in tests in Ember until we move the community over entirely to using
-    // `<template>` and local scope.
-    skip<TC extends TestContext>(
-      name: string,
-      callback?: (this: TC, assert: Assert) => void | Promise<unknown>
-    ): void;
-  }
-}
diff --git a/types/local-types.d.ts b/types/local-types.d.ts
deleted file mode 100644
index 2109bac6..00000000
--- a/types/local-types.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import 'ember-source/types';
-import 'ember-source/types/preview';

From b76fb1fa76ea9b74b3ef9e01ff389a4bb4e77d30 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 14:13:21 -0800
Subject: [PATCH 17/34] Fix type-tests and lint

---
 .eslintrc.js                                  | 54 ++++++++++++-------
 addon-test-support/adapter.ts                 |  2 +-
 addon-test-support/index.ts                   | 39 +++++++++-----
 .../test-isolation-validation.ts              |  6 +--
 docs/legacy.md                                |  2 -
 tsconfig.json                                 |  6 +--
 type-tests/api.ts                             | 51 +++++++-----------
 type-tests/tsconfig.json                      | 11 ++--
 8 files changed, 91 insertions(+), 80 deletions(-)

diff --git a/.eslintrc.js b/.eslintrc.js
index 7a07c074..20b911fc 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,5 +1,28 @@
 'use strict';
 
+const sharedTSOptions = {
+  extends: [
+    'eslint:recommended',
+    'plugin:@typescript-eslint/recommended',
+    'plugin:@typescript-eslint/recommended-requiring-type-checking',
+    'plugin:@typescript-eslint/strict',
+  ],
+  parser: '@typescript-eslint/parser',
+  plugins: ['@typescript-eslint'],
+  rules: {
+    '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
+    '@typescript-eslint/consistent-type-exports': 'error',
+    '@typescript-eslint/consistent-type-imports': 'error',
+    '@typescript-eslint/explicit-function-return-type': 'error',
+    '@typescript-eslint/method-signature-style': 'error',
+    '@typescript-eslint/no-confusing-void-expression': 'error',
+    '@typescript-eslint/no-redundant-type-constituents': 'error',
+    '@typescript-eslint/prefer-enum-initializers': 'error',
+    '@typescript-eslint/prefer-readonly': 'error',
+    '@typescript-eslint/promise-function-async': 'error',
+  },
+};
+
 module.exports = {
   root: true,
   extends: ['eslint:recommended', 'plugin:prettier/recommended'],
@@ -48,29 +71,24 @@ module.exports = {
     // ts files
     {
       files: ['**/*.ts'],
-      extends: [
-        'eslint:recommended',
-        'plugin:@typescript-eslint/recommended',
-        'plugin:@typescript-eslint/recommended-requiring-type-checking',
-        'plugin:@typescript-eslint/strict',
-      ],
-      parser: '@typescript-eslint/parser',
       parserOptions: {
         tsconfigRootDir: __dirname,
         project: ['./tsconfig.json'],
       },
-      plugins: ['@typescript-eslint'],
+      ...sharedTSOptions,
+    },
+
+    // ts-tests files
+    {
+      files: ['type-tests/**/*.ts'],
+      parserOptions: {
+        tsconfigRootDir: __dirname,
+        project: ['./type-tests/tsconfig.json'],
+      },
+      ...sharedTSOptions,
       rules: {
-        '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
-        '@typescript-eslint/consistent-type-exports': 'error',
-        '@typescript-eslint/consistent-type-imports': 'error',
-        '@typescript-eslint/explicit-function-return-type': 'error',
-        '@typescript-eslint/method-signature-style': 'error',
-        '@typescript-eslint/no-confusing-void-expression': 'error',
-        '@typescript-eslint/no-redundant-type-constituents': 'error',
-        '@typescript-eslint/prefer-enum-initializers': 'error',
-        '@typescript-eslint/prefer-readonly': 'error',
-        '@typescript-eslint/promise-function-async': 'error',
+        '@typescript-eslint/no-empty-function': 'off',
+        '@typescript-eslint/no-unused-vars': 'off',
       },
     },
 
diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index 4b421ca9..a1945cb5 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -5,7 +5,7 @@ import Ember from 'ember';
 
 import * as QUnit from 'qunit';
 
-import { isRecord, isTest } from 'ember-qunit/test-support/types/util';
+import { isRecord, isTest } from './types/util';
 
 function unhandledRejectionAssertion(current: unknown, error: unknown): void {
   let message: string;
diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index 5c96e3c1..c55c421f 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -112,14 +112,9 @@ export function setupTest(
  * Once invoked, all subsequent hooks.beforeEach and test invocations will
  * have access to the following:
  * * All of the methods / properties listed for `setupTest`
- * * this.render(...) - Renders the provided template snippet returning a
- * promise that resolves once rendering has completed
- * * An importable render function that de-sugars into this.render will be
- * the default output of blueprints
+ * * An importable render function
  * * this.element - Returns the native DOM element representing the element
  * that was rendered via this.render
- * * this.$(...) - When jQuery is present, executes a jQuery selector with
- * the current this.element as its root
  */
 export function setupRenderingTest(
   hooks: NestedHooks,
@@ -364,14 +359,18 @@ declare global {
      * module's queue has emptied, it will not run this hook again.
      */
     after<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
+      fn:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
      * Runs after each test.
      */
     afterEach<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
+      fn:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
@@ -379,7 +378,9 @@ declare global {
      */
     // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
     before<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
+      fn:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
@@ -387,7 +388,9 @@ declare global {
      */
     // SAFETY: this is just wildly, impossibly unsafe. QUnit cannot -- ever! --
     beforeEach<TC extends TestContext>(
-      fn: (this: TC, assert: Assert) => void | Promise<void>
+      fn:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
   }
 
@@ -413,7 +416,9 @@ declare global {
     // `<template>` and local scope.
     test<TC extends TestContext>(
       name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+      callback:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
@@ -438,7 +443,9 @@ declare global {
     // `<template>` and local scope.
     only<TC extends TestContext>(
       name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+      callback:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
@@ -457,7 +464,9 @@ declare global {
     // `<template>` and local scope.
     todo<TC extends TestContext>(
       name: string,
-      callback: (this: TC, assert: Assert) => void | Promise<unknown>
+      callback:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
 
     /**
@@ -479,7 +488,9 @@ declare global {
     // `<template>` and local scope.
     skip<TC extends TestContext>(
       name: string,
-      callback?: (this: TC, assert: Assert) => void | Promise<unknown>
+      callback?:
+        | ((this: TC, assert: Assert) => void)
+        | ((this: TC, assert: Assert) => Promise<void>)
     ): void;
   }
 }
diff --git a/addon-test-support/test-isolation-validation.ts b/addon-test-support/test-isolation-validation.ts
index fdf16e30..6dfc91fc 100644
--- a/addon-test-support/test-isolation-validation.ts
+++ b/addon-test-support/test-isolation-validation.ts
@@ -12,8 +12,8 @@ import {
 
 import * as QUnit from 'qunit';
 
-import type { Test } from 'ember-qunit/test-support/types/util';
-import { isTest } from 'ember-qunit/test-support/types/util';
+import type { Test } from './types/util';
+import { isTest } from './types/util';
 
 /**
  * Detects if a specific test isn't isolated. A test is considered
@@ -34,7 +34,7 @@ export function detectIfTestNotIsolated(test: Test, message = ''): void {
     const { debugInfo } = getSettledState();
 
     console.group(`${test.module.name}: ${test.testName}`);
-    debugInfo?.toConsole();
+    debugInfo.toConsole();
     console.groupEnd();
 
     assert('detectIfTestNotIsolated called on skipped test', !test.skip);
diff --git a/docs/legacy.md b/docs/legacy.md
index 13c48db3..e8e12529 100644
--- a/docs/legacy.md
+++ b/docs/legacy.md
@@ -143,8 +143,6 @@ test('It can set its child', function(assert) {
 ## Advanced Usage
 ### Setting the resolver
 
-<!-- FIXME: setResolver is not actually exported from ember-qunit. It comes from @ember/test-helpers -->
-
 ```js
 // if you don't have a custom resolver, do it like this:
 setResolver(Ember.DefaultResolver.create({ namespace: App }));
diff --git a/tsconfig.json b/tsconfig.json
index b01885cf..9988f562 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,10 +8,8 @@
     "paths": {
       "dummy/tests/*": ["tests/*"],
       "dummy/*": ["tests/dummy/app/*", "app/*"],
-      "ember-qunit": ["addon"],
-      "ember-qunit/*": ["addon/*"],
-      "ember-qunit/test-support": ["addon-test-support"],
-      "ember-qunit/test-support/*": ["addon-test-support/*"],
+      "ember-qunit": ["addon-test-support"],
+      "ember-qunit/*": ["addon-test-support/*"],
       "*": ["types/*"]
     }
   },
diff --git a/type-tests/api.ts b/type-tests/api.ts
index ccc9385c..f86305fe 100644
--- a/type-tests/api.ts
+++ b/type-tests/api.ts
@@ -1,13 +1,7 @@
-// These tests were ported directly from DefinitelyTyped and are unlikely to be
-// 100% desireable for the future.
 import { hbs } from 'ember-cli-htmlbars';
-import { module } from 'qunit';
+import { module, test, skip, only, todo } from 'qunit';
 import {
   start,
-  test,
-  skip,
-  only,
-  todo,
   setupRenderingTest,
   setupTest,
   SetupTestOptions,
@@ -22,22 +16,21 @@ import type EmberObject from '@ember/object';
 module('rendering', function (hooks) {
   setupRenderingTest(hooks);
 
-  test('it renders', function (this: RenderingTestContext, assert) {
+  test('it renders', async function (this: RenderingTestContext, assert) {
     assert.expect(2);
 
     // setup the outer context
     this.set('value', 'cat');
 
     // render the component
-    this.render(hbs`
-            {{ x-foo value=value action="result" }}
-        `);
+    await render(hbs`
+      {{ x-foo value=value action="result" }}
+    `);
 
-    // has to be a template
-    // @ts-expect-error
-    this.render();
-    // @ts-expect-error
-    this.render('{{ x-foo value=value action="result" }}');
+    // @ts-expect-error has to be a template
+    await render();
+    // @ts-expect-error has to be a template
+    await render('{{ x-foo value=value action="result" }}');
 
     const el = this.element.querySelector('div');
     assert.equal(el?.innerText, 'cat', 'The component shows the correct value');
@@ -67,12 +60,13 @@ module('rendering', function (hooks) {
     const inputFormat2 = this.get('inputFormat');
 
     // render the component on the page
-    this.render(hbs`<div>bar</div>`);
+    await render(hbs`<div>bar</div>`);
     assert.equal(this.element.querySelector('div')?.innerText, 'bar');
   });
 });
 
 module('misc and async', function (hooks) {
+  // eslint-disable-next-line @typescript-eslint/require-await
   hooks.beforeEach(async function (assert) {
     assert.ok(true, 'hooks can be async');
   });
@@ -91,13 +85,10 @@ module('misc and async', function (hooks) {
     assert.equal(subject.get('result'), 'bar');
   });
 
-  // This test is intended to ensure the appropriate behavior for @typescript-eslint/no-misused-promises.
-  // However, we don't actually use typescript-eslint in this project and tslint has no equivalent,
-  // so we can't properly test it.
   test('it can be async', async function (this: RenderingTestContext, assert) {
     assert.expect(1);
 
-    await this.render(hbs`<p>Hello</p>`);
+    await render(hbs`<p>Hello</p>`);
 
     assert.ok(true, 'rendered');
   });
@@ -112,34 +103,28 @@ module('misc and async', function (hooks) {
   skip('it can skip async', async function (this: RenderingTestContext, assert) {
     assert.expect(1);
 
-    await this.render(hbs`<p>Hello</p>`);
+    await render(hbs`<p>Hello</p>`);
 
     assert.ok(true, 'rendered');
   });
 
-  // This test is intended to ensure the appropriate behavior for @typescript-eslint/no-misused-promises.
-  // However, we don't actually use typescript-eslint in this project and tslint has no equivalent,
-  // so we can't properly test it.
   only(
     'it can only run async',
     async function (this: RenderingTestContext, assert) {
       assert.expect(1);
 
-      await this.render(hbs`<p>Hello</p>`);
+      await render(hbs`<p>Hello</p>`);
 
       assert.ok(true, 'rendered');
     }
   );
 
-  // This test is intended to ensure the appropriate behavior for @typescript-eslint/no-misused-promises.
-  // However, we don't actually use typescript-eslint in this project and tslint has no equivalent,
-  // so we can't properly test it.
   todo(
     'it can have an async todo',
     async function (this: RenderingTestContext, assert) {
       assert.expect(1);
 
-      await this.render(hbs`<p>Hello</p>`);
+      await render(hbs`<p>Hello</p>`);
 
       assert.ok(true, 'rendered');
     }
@@ -148,11 +133,11 @@ module('misc and async', function (hooks) {
 // end tests ported from ember-test-helpers
 
 module('returning a promise', function () {
-  test('it can return Promise<void>', function (this: TestContext, assert) {
+  test('it can return Promise<void>', async function (this: TestContext, assert) {
     return Promise.resolve();
   });
 
-  test('it can return a non-empty Promise', function (this: TestContext, assert) {
+  test('it can return a non-empty Promise', async function (this: TestContext, assert) {
     return Promise.resolve('foo');
   });
 });
@@ -321,7 +306,7 @@ start();
 
 module('with setup options', function (hooks) {
   // $ExpectType SetupTestOptions | undefined
-  type SetupTestOptions = Parameters<typeof setupTest>[1];
+  type _SetupTestOptions = Parameters<typeof setupTest>[1];
   // $ExpectType SetupTestOptions | undefined
   type SetupRenderingTestOptions = Parameters<typeof setupRenderingTest>[1];
   // $ExpectType SetupTestOptions | undefined
diff --git a/type-tests/tsconfig.json b/type-tests/tsconfig.json
index 9b0a3352..aa5bffee 100644
--- a/type-tests/tsconfig.json
+++ b/type-tests/tsconfig.json
@@ -1,11 +1,12 @@
 {
   "extends": "@tsconfig/ember",
   "compilerOptions": {
-    "baseUrl": ".",
+    "baseUrl": "..",
     "paths": {
-      "ember-qunit": [
-        "./index.d.ts"
-      ],
+      "ember-qunit": ["addon-test-support"],
+      "ember-qunit/*": ["addon-test-support/*"],
+      "*": ["types/*"]
     }
-  }
+  },
+  "include": ["api.ts", "../types/**/*"]
 }

From 6d9a48d4fc0cfa83f9aeabf152aacc7e3053507c Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 14:18:45 -0800
Subject: [PATCH 18/34] Fix typesVersions

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 597fc3d9..c1eb633c 100644
--- a/package.json
+++ b/package.json
@@ -136,7 +136,7 @@
   "typesVersions": {
     "*": {
       "*": [
-        "test-support/*"
+        "addon-test-support/*"
       ]
     }
   }

From d114caa97e5bf2b0ea4599e65d2f694b3e84f3ad Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 15:03:58 -0800
Subject: [PATCH 19/34] Clean up waitForSettled types

---
 addon-test-support/index.ts | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index c55c421f..c97302fd 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -32,7 +32,6 @@ import QUnitAdapter from './adapter';
 import { installTestNotIsolatedHook } from './test-isolation-validation';
 import { loadTests } from './test-loader';
 
-// FIXME: What is this about?
 let waitForSettled = true;
 
 /**
@@ -48,8 +47,7 @@ export interface SetupTestOptions {
 }
 
 type PrivateSetupOptions = SetupTestOptions & {
-  // FIXME: What is this about?
-  waitForSettled?: boolean;
+  waitForSettled: boolean;
 };
 
 /**

From 8c419e23aaf3b03f179905882d228879fa49504d Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 15:43:45 -0800
Subject: [PATCH 20/34] Use exported @ember/test-helpers options

---
 addon-test-support/index.ts | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index c97302fd..f62294ce 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -12,9 +12,13 @@ if (typeof Testem !== 'undefined') {
   Testem.hookIntoTestFramework();
 }
 
-import type { Resolver } from '@ember/owner';
 import { _backburner } from '@ember/runloop';
-import type { BaseContext, TestContext } from '@ember/test-helpers';
+import type {
+  BaseContext,
+  SetupContextOptions,
+  TeardownContextOptions,
+  TestContext,
+} from '@ember/test-helpers';
 import {
   getTestMetadata,
   resetOnerror,
@@ -39,16 +43,9 @@ let waitForSettled = true;
  * customize this. It is exported primarily so that end user app code can name
  * it when passing it back to the framework.
  */
-export interface SetupTestOptions {
-  /**
-   * The resolver to use when instantiating container-managed entities in the test.
-   */
-  resolver?: Resolver | undefined;
-}
+export type SetupTestOptions = SetupContextOptions;
 
-type PrivateSetupOptions = SetupTestOptions & {
-  waitForSettled: boolean;
-};
+type PrivateSetupOptions = SetupContextOptions & TeardownContextOptions;
 
 /**
  * Sets up tests that do not need to render snippets of templates.

From 2039091785e4427951d1b32873a75aefbdd38414 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 15:46:25 -0800
Subject: [PATCH 21/34] Add fixme

---
 types/ember-cli-test-loader/test-support/index.d.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/types/ember-cli-test-loader/test-support/index.d.ts b/types/ember-cli-test-loader/test-support/index.d.ts
index c5ee5ca6..f46a7dd8 100644
--- a/types/ember-cli-test-loader/test-support/index.d.ts
+++ b/types/ember-cli-test-loader/test-support/index.d.ts
@@ -1,3 +1,4 @@
+// FIXME: Upstream
 declare module 'ember-cli-test-loader/test-support/index' {
   export default class TestLoader {
     static load(): void;

From 9f278ae92a317239b61a99fede53f3a91dfa61f9 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 3 Jan 2023 16:20:07 -0800
Subject: [PATCH 22/34] Set isTypeScriptProject to true

---
 .ember-cli | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.ember-cli b/.ember-cli
index 4ccb4bf4..4adaaf6d 100644
--- a/.ember-cli
+++ b/.ember-cli
@@ -11,5 +11,5 @@
   Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript
   rather than JavaScript by default, when a TypeScript version of a given blueprint is available.
   */
-  "isTypeScriptProject": false
+  "isTypeScriptProject": true
 }

From c658add8c333712a8386947410b3bf36a8f6e0cf Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Wed, 4 Jan 2023 14:49:59 -0800
Subject: [PATCH 23/34] Use ember-cli-test-loader types

---
 addon-test-support/test-loader.ts              |  6 +++---
 package.json                                   |  2 +-
 .../test-support/index.d.ts                    | 18 ------------------
 yarn.lock                                      |  6 ++----
 4 files changed, 6 insertions(+), 26 deletions(-)
 delete mode 100644 types/ember-cli-test-loader/test-support/index.d.ts

diff --git a/addon-test-support/test-loader.ts b/addon-test-support/test-loader.ts
index 4eaf9475..edb8ed45 100644
--- a/addon-test-support/test-loader.ts
+++ b/addon-test-support/test-loader.ts
@@ -14,7 +14,7 @@ addModuleIncludeMatcher(function (moduleName) {
   return moduleName.endsWith('.jshint');
 });
 
-let moduleLoadFailures: Array<{ stack: unknown }> = [];
+let moduleLoadFailures: unknown[] = [];
 
 QUnit.done(function () {
   const length = moduleLoadFailures.length;
@@ -35,7 +35,7 @@ QUnit.done(function () {
 });
 
 export class TestLoader extends AbstractTestLoader {
-  moduleLoadFailure(moduleName: string, error: { stack: unknown }): void {
+  moduleLoadFailure(moduleName: string, error: unknown): void {
     moduleLoadFailures.push(error);
 
     QUnit.module('TestLoader Failures');
@@ -61,5 +61,5 @@ export class TestLoader extends AbstractTestLoader {
    @method loadTests
  */
 export function loadTests(): void {
-  new TestLoader().loadModules();
+  TestLoader.load();
 }
diff --git a/package.json b/package.json
index c1eb633c..4244c9b7 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
     "common-tags": "^1.8.0",
     "ember-auto-import": "^2.6.0",
     "ember-cli-babel": "^7.26.11",
-    "ember-cli-test-loader": "^3.0.0",
+    "ember-cli-test-loader": "file:.yalc/ember-cli-test-loader",
     "ember-cli-typescript": "^5.2.1",
     "resolve-package-path": "^4.0.3",
     "silent-error": "^1.1.1",
diff --git a/types/ember-cli-test-loader/test-support/index.d.ts b/types/ember-cli-test-loader/test-support/index.d.ts
deleted file mode 100644
index f46a7dd8..00000000
--- a/types/ember-cli-test-loader/test-support/index.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// FIXME: Upstream
-declare module 'ember-cli-test-loader/test-support/index' {
-  export default class TestLoader {
-    static load(): void;
-    shouldLoadModule(moduleName: string): boolean;
-    listModules(): string[];
-    listTestModules(): string[];
-    loadModules(): void;
-    require(moduleName: string): void;
-    unsee(moduleName: string): void;
-    moduleLoadFailure(moduleName: string, error: { stack: unknown }): void;
-  }
-
-  type Matcher = (moduleName: string) => boolean;
-
-  export function addModuleExcludeMatcher(matcher: Matcher): void;
-  export function addModuleIncludeMatcher(matcher: Matcher): void;
-}
diff --git a/yarn.lock b/yarn.lock
index c3c8a5d4..ac82af0f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4241,12 +4241,10 @@ ember-cli-terser@^4.0.2:
   dependencies:
     broccoli-terser-sourcemap "^4.1.0"
 
-ember-cli-test-loader@^3.0.0:
+"ember-cli-test-loader@file:.yalc/ember-cli-test-loader":
   version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-3.0.0.tgz#1c036fc48de36155355fcda3266af63f977826f1"
-  integrity sha512-wfFRBrfO9gaKScYcdQxTfklx9yp1lWK6zv1rZRpkas9z2SHyJojF7NOQRWQgSB3ypm7vfpiF8VsFFVVr7VBzAQ==
   dependencies:
-    ember-cli-babel "^7.13.2"
+    ember-cli-babel "^7.23.0"
 
 ember-cli-typescript-blueprint-polyfill@^0.1.0:
   version "0.1.0"

From 8a2fa1256e5ee8d34ca768723680e2c0560a7d3d Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Wed, 4 Jan 2023 16:43:55 -0800
Subject: [PATCH 24/34] Use updated qunit types

---
 addon-test-support/adapter.ts                 |  1 -
 addon-test-support/index.ts                   | 16 ++--
 addon-test-support/qunit-configuration.ts     |  4 +-
 .../test-isolation-validation.ts              |  3 +-
 addon-test-support/test-loader.ts             |  6 +-
 addon-test-support/types/util.ts              | 77 +------------------
 package.json                                  |  2 +-
 7 files changed, 15 insertions(+), 94 deletions(-)

diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index a1945cb5..4d96984a 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -35,7 +35,6 @@ function unhandledRejectionAssertion(current: unknown, error: unknown): void {
     actual: false,
     expected: true,
     message: message,
-    // @ts-expect-error FIXME: Update qunit type https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/docs/callbacks/QUnit.log.md?plain=1#L32
     source,
   });
 }
diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index f62294ce..82679ea1 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -81,13 +81,15 @@ export function setupTest(
       async function QUnit_pauseTest(): Promise<void> {
         assert.timeout(-1); // prevent the test from timing out
 
+        const timeout = QUnit.config.timeout;
+
         // This is a temporary work around for
         // https://github.com/emberjs/ember-qunit/issues/496 this clears the
         // timeout that would fail the test when it hits the global testTimeout
         // value.
-        // @ts-expect-error FIXME
-        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
-        clearTimeout(QUnit.config.timeout);
+        if (timeout !== null && timeout !== undefined) {
+          clearTimeout(timeout);
+        }
         await originalPauseTest.call(this);
       };
   });
@@ -164,9 +166,7 @@ export function setupTestContainer(): void {
     return;
   }
 
-  // @ts-expect-error FIXME
-  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
-  const params: Record<string, unknown> = QUnit.urlParams;
+  const params = QUnit.urlParams;
 
   if (params['devmode'] || params['fullscreencontainer']) {
     testContainer.classList.add('ember-testing-container-full-screen');
@@ -238,9 +238,7 @@ export function setupResetOnerror(): void {
 export function setupTestIsolationValidation(delay?: number | undefined): void {
   waitForSettled = false;
   _backburner.DEBUG = true;
-  // @ts-expect-error FIXME
-  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
-  QUnit.on('testStart', () => {
+  QUnit.testStart(() => {
     installTestNotIsolatedHook(delay);
   });
 }
diff --git a/addon-test-support/qunit-configuration.ts b/addon-test-support/qunit-configuration.ts
index 9c563b95..b8d60e53 100644
--- a/addon-test-support/qunit-configuration.ts
+++ b/addon-test-support/qunit-configuration.ts
@@ -5,6 +5,4 @@ QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container' });
 QUnit.config.urlConfig.push({ id: 'nolint', label: 'Disable Linting' });
 QUnit.config.urlConfig.push({ id: 'devmode', label: 'Development mode' });
 
-// @ts-expect-error FIXME qunit types are incorrect
-// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
-QUnit.config.testTimeout = QUnit.urlParams.devmode ? null : 60000; //Default Test Timeout 60 Seconds
+QUnit.config.testTimeout = QUnit.urlParams['devmode'] ? null : 60000; //Default Test Timeout 60 Seconds
diff --git a/addon-test-support/test-isolation-validation.ts b/addon-test-support/test-isolation-validation.ts
index 6dfc91fc..31a1e394 100644
--- a/addon-test-support/test-isolation-validation.ts
+++ b/addon-test-support/test-isolation-validation.ts
@@ -12,7 +12,6 @@ import {
 
 import * as QUnit from 'qunit';
 
-import type { Test } from './types/util';
 import { isTest } from './types/util';
 
 /**
@@ -29,7 +28,7 @@ import { isTest } from './types/util';
  * @param {string} testInfo.module The name of the test module
  * @param {string} testInfo.name The test name
  */
-export function detectIfTestNotIsolated(test: Test, message = ''): void {
+export function detectIfTestNotIsolated(test: QUnit.Test, message = ''): void {
   if (!isSettled()) {
     const { debugInfo } = getSettledState();
 
diff --git a/addon-test-support/test-loader.ts b/addon-test-support/test-loader.ts
index edb8ed45..59b2124a 100644
--- a/addon-test-support/test-loader.ts
+++ b/addon-test-support/test-loader.ts
@@ -5,9 +5,9 @@ import AbstractTestLoader, {
 import * as QUnit from 'qunit';
 
 addModuleExcludeMatcher(function (moduleName) {
-  // @ts-expect-error FIXME Qunit types argh
-  // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
-  return QUnit.urlParams.nolint && /\.(jshint|lint-test)$/.test(moduleName);
+  return (
+    !!QUnit.urlParams['nolint'] && /\.(jshint|lint-test)$/.test(moduleName)
+  );
 });
 
 addModuleIncludeMatcher(function (moduleName) {
diff --git a/addon-test-support/types/util.ts b/addon-test-support/types/util.ts
index 37287ff5..abd0966e 100644
--- a/addon-test-support/types/util.ts
+++ b/addon-test-support/types/util.ts
@@ -1,83 +1,10 @@
+import type { Test } from 'qunit';
+
 /** Checks if the given value is a `Record<string, unknown>`. */
 export function isRecord(value: unknown): value is Record<string, unknown> {
   return value !== null && typeof value === 'object';
 }
 
-type Hook = (assert: Assert) => void | Promise<void>;
-
-type TestCallback = (assert: Assert) => void | Promise<void>;
-
-// https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/src/core/config.js#L84
-interface Module {
-  name: string;
-  tests: Array<{ name: string; id: string; skip: boolean }>;
-  childModules: Module[]; // FIXME: verify
-  testsRun: number;
-  testsIgnored: number;
-  hooks: {
-    before: Hook[];
-    beforeEach: Hook[];
-    afterEach: Hook[];
-    after: Hook[];
-  };
-  skip?: boolean;
-  ignored?: boolean;
-}
-
-// FIXME: What is the appropriate Test type? There doesn't appear to be a test type exported from qunit
-// https://github.com/qunitjs/qunit/blob/main/src/test.js#L23
-interface TestBase {
-  testId: string;
-  testName: string;
-  expected: null | number;
-  assertions: Array<{ result: boolean; message: string }>;
-  module: Module;
-  steps: unknown[];
-  timeout: undefined;
-  data: unknown;
-  withData: boolean;
-  pauses: Map<string, unknown>;
-  nextPauseId: 1;
-  stackOffset: 0 | 1 | 2 | 3 | 5;
-  errorForStack: Error;
-  testReport: unknown;
-  stack: string;
-  before: () => unknown;
-  run: () => unknown;
-  after: () => void;
-  queueGlobalHook: (hook: unknown, hookName: unknown) => () => unknown;
-  queueHook: (
-    hook: unknown,
-    hookName: unknown,
-    hookOwner: unknown
-  ) => () => unknown;
-  hooks: (handler: unknown) => unknown;
-  finish: () => unknown;
-  preserveTestEnvironment: () => unknown;
-  queue: () => void;
-  pushResult: (resultInfo: unknown) => void;
-  pushFailure: (message: string, source: string, actual: unknown) => void;
-  skip?: true;
-  callback: TestCallback;
-  todo?: boolean;
-  async?: boolean;
-}
-
-export interface AssertionTest extends TestBase {
-  assert: Assert;
-}
-
-export interface SkipTest extends TestBase {
-  skip: true;
-  async: false;
-}
-export interface TodoTest extends TestBase {
-  todo: true;
-  assert: Assert;
-}
-
-export type Test = AssertionTest | SkipTest | TodoTest;
-
 export function isTest(value: unknown): value is Test {
   return isRecord(value) && 'testId' in value;
 }
diff --git a/package.json b/package.json
index 4244c9b7..9584b0f6 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
     "common-tags": "^1.8.0",
     "ember-auto-import": "^2.6.0",
     "ember-cli-babel": "^7.26.11",
-    "ember-cli-test-loader": "file:.yalc/ember-cli-test-loader",
     "ember-cli-typescript": "^5.2.1",
     "resolve-package-path": "^4.0.3",
     "silent-error": "^1.1.1",
@@ -66,6 +65,7 @@
     "ember-cli-htmlbars": "^6.2.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-terser": "^4.0.2",
+    "ember-cli-test-loader": "file:.yalc/ember-cli-test-loader",
     "ember-disable-prototype-extensions": "^1.1.3",
     "ember-load-initializers": "^2.1.2",
     "ember-resolver": "^9.0.1",

From aa12055caed1e0a14caf116fd007065b33ba9ff5 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Thu, 5 Jan 2023 10:35:11 -0800
Subject: [PATCH 25/34] Don't use private timeout type

---
 addon-test-support/index.ts | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index 82679ea1..c1e00042 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -81,12 +81,17 @@ export function setupTest(
       async function QUnit_pauseTest(): Promise<void> {
         assert.timeout(-1); // prevent the test from timing out
 
-        const timeout = QUnit.config.timeout;
-
         // This is a temporary work around for
         // https://github.com/emberjs/ember-qunit/issues/496 this clears the
         // timeout that would fail the test when it hits the global testTimeout
         // value.
+        // https://github.com/DefinitelyTyped/DefinitelyTyped/pull/63805#issuecomment-1372408802
+        const timeout = (
+          QUnit.config as unknown as {
+            // https://github.com/qunitjs/qunit/blob/fc278e8c0d7e90ec42e47b47eee1cc85c9a9efaf/src/test.js#L752
+            timeout: ReturnType<typeof setTimeout> | null | undefined;
+          }
+        ).timeout;
         if (timeout !== null && timeout !== undefined) {
           clearTimeout(timeout);
         }

From 815c4c08462f6e229e5ba59414d12410418fbbe3 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Thu, 5 Jan 2023 10:36:57 -0800
Subject: [PATCH 26/34] Use override for moduleLoadFailure override

---
 addon-test-support/test-loader.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/addon-test-support/test-loader.ts b/addon-test-support/test-loader.ts
index 59b2124a..1e16069a 100644
--- a/addon-test-support/test-loader.ts
+++ b/addon-test-support/test-loader.ts
@@ -35,7 +35,7 @@ QUnit.done(function () {
 });
 
 export class TestLoader extends AbstractTestLoader {
-  moduleLoadFailure(moduleName: string, error: unknown): void {
+  override moduleLoadFailure(moduleName: string, error: unknown): void {
     moduleLoadFailures.push(error);
 
     QUnit.module('TestLoader Failures');

From f68c09e56fbb17f86ee6b6b85e4aa6e7e2aa2bbe Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Thu, 5 Jan 2023 10:58:03 -0800
Subject: [PATCH 27/34] Remove FIXMEs from ember classic junk

---
 addon-test-support/adapter.ts | 4 ++--
 addon-test-support/index.ts   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/addon-test-support/adapter.ts b/addon-test-support/adapter.ts
index 4d96984a..ed3c2a58 100644
--- a/addon-test-support/adapter.ts
+++ b/addon-test-support/adapter.ts
@@ -48,7 +48,7 @@ interface QUnitAdapter extends EmberTestAdapter {
   qunit: QUnit;
 }
 
-// @ts-expect-error FIXME `extend` does not exist on Adapter
+// @ts-expect-error `extend` does not exist on Adapter
 // eslint-disable-next-line @typescript-eslint/no-unsafe-call
 let Adapter = Ember.Test.Adapter.extend({
   init(this: QUnitAdapter) {
@@ -93,7 +93,7 @@ let Adapter = Ember.Test.Adapter.extend({
 // automatically re-thrown and will therefore hit QUnit's own global error
 // handler (therefore appropriately causing test failure)
 if (!hasEmberVersion(2, 17)) {
-  // @ts-expect-error FIXME `extend` does not exist on Adapter
+  // @ts-expect-error `extend` does not exist on Adapter
   // eslint-disable-next-line @typescript-eslint/no-unsafe-call
   Adapter = Adapter.extend({
     exception(error: unknown) {
diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index c1e00042..510979c2 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -196,7 +196,7 @@ export function startTests(): void {
    @method setupTestAdapter
  */
 export function setupTestAdapter(): void {
-  // @ts-expect-error FIXME
+  // @ts-expect-error Adapter doesn't have `create`
   // eslint-disable-next-line @typescript-eslint/no-unsafe-call
   Ember.Test.adapter = QUnitAdapter.create() as typeof QUnitAdapter;
 }

From f9c8fb055c334c77fc7b1bb6b4cba478cfea1ace Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Thu, 5 Jan 2023 16:03:11 -0800
Subject: [PATCH 28/34] Remove remaining FIXMEs

---
 addon-test-support/index.ts                     | 8 ++++----
 addon-test-support/test-isolation-validation.ts | 3 +--
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts
index 510979c2..4d6bebdb 100644
--- a/addon-test-support/index.ts
+++ b/addon-test-support/index.ts
@@ -5,9 +5,9 @@ export { loadTests } from './test-loader';
 
 import './qunit-configuration';
 
-// @ts-expect-error FIXME
+// @ts-expect-error Testem has no types
 if (typeof Testem !== 'undefined') {
-  // @ts-expect-error FIXME
+  // @ts-expect-error Testem has no types
   // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
   Testem.hookIntoTestFramework();
 }
@@ -209,12 +209,12 @@ export function setupTestAdapter(): void {
  */
 export function setupEmberTesting(): void {
   QUnit.testStart(() => {
-    // @ts-expect-error FIXME
+    // @ts-expect-error Ember.testing type is readonly
     Ember.testing = true;
   });
 
   QUnit.testDone(() => {
-    // @ts-expect-error FIXME
+    // @ts-expect-error Ember.testing type is readonly
     Ember.testing = false;
   });
 }
diff --git a/addon-test-support/test-isolation-validation.ts b/addon-test-support/test-isolation-validation.ts
index 31a1e394..a56ad14b 100644
--- a/addon-test-support/test-isolation-validation.ts
+++ b/addon-test-support/test-isolation-validation.ts
@@ -1,7 +1,7 @@
 /* eslint-disable no-console */
 
 import { assert } from '@ember/debug';
-// @ts-expect-error FIXME
+// @ts-expect-error _cancelTimers is private
 import { _cancelTimers as cancelTimers } from '@ember/runloop';
 import {
   getDebugInfo,
@@ -121,7 +121,6 @@ export function installTestNotIsolatedHook(delay = 50): void {
           // canceling timers here isn't perfect, but is as good as we can do
           // to attempt to prevent future tests from failing due to this test's
           // leakage
-          // FIXME
           // eslint-disable-next-line @typescript-eslint/no-unsafe-call
           cancelTimers();
 

From e82376387852544df5852e9b61d7119e84147183 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 30 Jan 2023 13:21:38 -0800
Subject: [PATCH 29/34] Revert to ambient ember-cli-test-loader types

---
 addon-test-support/test-loader.ts             |  2 +-
 package.json                                  |  2 +-
 .../test-support/index.d.ts                   | 32 +++++++++++++++++++
 yarn.lock                                     |  6 ++--
 4 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 types/ember-cli-test-loader/test-support/index.d.ts

diff --git a/addon-test-support/test-loader.ts b/addon-test-support/test-loader.ts
index 1e16069a..9e4f60a4 100644
--- a/addon-test-support/test-loader.ts
+++ b/addon-test-support/test-loader.ts
@@ -34,7 +34,7 @@ QUnit.done(function () {
   }
 });
 
-export class TestLoader extends AbstractTestLoader {
+class TestLoader extends AbstractTestLoader {
   override moduleLoadFailure(moduleName: string, error: unknown): void {
     moduleLoadFailures.push(error);
 
diff --git a/package.json b/package.json
index 9584b0f6..aa1ce6fe 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
     "ember-cli-htmlbars": "^6.2.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-terser": "^4.0.2",
-    "ember-cli-test-loader": "file:.yalc/ember-cli-test-loader",
+    "ember-cli-test-loader": "^3.0.0",
     "ember-disable-prototype-extensions": "^1.1.3",
     "ember-load-initializers": "^2.1.2",
     "ember-resolver": "^9.0.1",
diff --git a/types/ember-cli-test-loader/test-support/index.d.ts b/types/ember-cli-test-loader/test-support/index.d.ts
new file mode 100644
index 00000000..726b2f1d
--- /dev/null
+++ b/types/ember-cli-test-loader/test-support/index.d.ts
@@ -0,0 +1,32 @@
+declare module 'ember-cli-test-loader/test-support/index' {
+  export default class TestLoader {
+    /** Instantiates a new TestLoader and loads the modules. */
+    static load(): void;
+
+    /**
+     * Can be overridden in order to customize the criteria for identifying test
+     * modules.
+     */
+    shouldLoadModule(moduleName: string): boolean;
+
+    moduleLoadFailure(moduleName: string, error: unknown): void;
+
+    /** Use `TestLoader.load()` static method instead. */
+    protected constructor();
+
+    // Assumed private:
+    // loadModules(): void;
+    // listModules(): string[];
+    // listTestModules(): string[];
+    // require(moduleName: string): void;
+    // unsee(moduleName: string): void;
+  }
+
+  export function addModuleExcludeMatcher(
+    matcher: (moduleName: string) => boolean
+  ): void;
+
+  export function addModuleIncludeMatcher(
+    matcher: (moduleName: string) => boolean
+  ): void;
+}
diff --git a/yarn.lock b/yarn.lock
index ac82af0f..c3c8a5d4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4241,10 +4241,12 @@ ember-cli-terser@^4.0.2:
   dependencies:
     broccoli-terser-sourcemap "^4.1.0"
 
-"ember-cli-test-loader@file:.yalc/ember-cli-test-loader":
+ember-cli-test-loader@^3.0.0:
   version "3.0.0"
+  resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-3.0.0.tgz#1c036fc48de36155355fcda3266af63f977826f1"
+  integrity sha512-wfFRBrfO9gaKScYcdQxTfklx9yp1lWK6zv1rZRpkas9z2SHyJojF7NOQRWQgSB3ypm7vfpiF8VsFFVVr7VBzAQ==
   dependencies:
-    ember-cli-babel "^7.23.0"
+    ember-cli-babel "^7.13.2"
 
 ember-cli-typescript-blueprint-polyfill@^0.1.0:
   version "0.1.0"

From a2ffc437174767514620991629000865bce96619 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 31 Jan 2023 11:11:45 -0800
Subject: [PATCH 30/34] Fix config

Consuming packages were looking at the TS files instead of the .d.ts files
---
 package.json | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/package.json b/package.json
index aa1ce6fe..e3e99422 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
     "common-tags": "^1.8.0",
     "ember-auto-import": "^2.6.0",
     "ember-cli-babel": "^7.26.11",
+    "ember-cli-test-loader": "^3.0.0",
     "ember-cli-typescript": "^5.2.1",
     "resolve-package-path": "^4.0.3",
     "silent-error": "^1.1.1",
@@ -65,7 +66,6 @@
     "ember-cli-htmlbars": "^6.2.0",
     "ember-cli-inject-live-reload": "^2.1.0",
     "ember-cli-terser": "^4.0.2",
-    "ember-cli-test-loader": "^3.0.0",
     "ember-disable-prototype-extensions": "^1.1.3",
     "ember-load-initializers": "^2.1.2",
     "ember-resolver": "^9.0.1",
@@ -132,12 +132,5 @@
   "volta": {
     "node": "14.19.1",
     "yarn": "1.22.18"
-  },
-  "typesVersions": {
-    "*": {
-      "*": [
-        "addon-test-support/*"
-      ]
-    }
   }
 }

From f13fd8f8e37a9e0dac0abea576c6c4f619b450b9 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Tue, 31 Jan 2023 11:34:32 -0800
Subject: [PATCH 31/34] Upgrade @typescript-eslint dependencies

---
 package.json |  4 +--
 yarn.lock    | 99 ++++++++++++++++++++++++++--------------------------
 2 files changed, 52 insertions(+), 51 deletions(-)

diff --git a/package.json b/package.json
index e3e99422..218efffd 100644
--- a/package.json
+++ b/package.json
@@ -58,8 +58,8 @@
     "@tsconfig/ember": "^2.0.0",
     "@types/qunit": "^2.19.4",
     "@types/rsvp": "^4.0.4",
-    "@typescript-eslint/eslint-plugin": "^5.45.1",
-    "@typescript-eslint/parser": "^5.45.1",
+    "@typescript-eslint/eslint-plugin": "^5.50.0",
+    "@typescript-eslint/parser": "^5.50.0",
     "ember-angle-bracket-invocation-polyfill": "^3.0.2",
     "ember-cli": "~4.10.0",
     "ember-cli-dependency-checker": "^3.3.1",
diff --git a/yarn.lock b/yarn.lock
index c3c8a5d4..78395a01 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1742,87 +1742,88 @@
   resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
   integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
 
-"@typescript-eslint/eslint-plugin@^5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.1.tgz#ee5b51405f6c9ee7e60e4006d68c69450d3b4536"
-  integrity sha512-cOizjPlKEh0bXdFrBLTrI/J6B/QMlhwE9auOov53tgB+qMukH6/h8YAK/qw+QJGct/PTbdh2lytGyipxCcEtAw==
-  dependencies:
-    "@typescript-eslint/scope-manager" "5.45.1"
-    "@typescript-eslint/type-utils" "5.45.1"
-    "@typescript-eslint/utils" "5.45.1"
+"@typescript-eslint/eslint-plugin@^5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.50.0.tgz#fb48c31cadc853ffc1dc35373f56b5e2a8908fe9"
+  integrity sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==
+  dependencies:
+    "@typescript-eslint/scope-manager" "5.50.0"
+    "@typescript-eslint/type-utils" "5.50.0"
+    "@typescript-eslint/utils" "5.50.0"
     debug "^4.3.4"
+    grapheme-splitter "^1.0.4"
     ignore "^5.2.0"
     natural-compare-lite "^1.4.0"
     regexpp "^3.2.0"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/parser@^5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.1.tgz#6440ec283fa1373a12652d4e2fef4cb6e7b7e8c6"
-  integrity sha512-JQ3Ep8bEOXu16q0ztsatp/iQfDCtvap7sp/DKo7DWltUquj5AfCOpX2zSzJ8YkAVnrQNqQ5R62PBz2UtrfmCkA==
+"@typescript-eslint/parser@^5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.50.0.tgz#a33f44b2cc83d1b7176ec854fbecd55605b0b032"
+  integrity sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.45.1"
-    "@typescript-eslint/types" "5.45.1"
-    "@typescript-eslint/typescript-estree" "5.45.1"
+    "@typescript-eslint/scope-manager" "5.50.0"
+    "@typescript-eslint/types" "5.50.0"
+    "@typescript-eslint/typescript-estree" "5.50.0"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.45.1.tgz#5b87d025eec7035d879b99c260f03be5c247883c"
-  integrity sha512-D6fCileR6Iai7E35Eb4Kp+k0iW7F1wxXYrOhX/3dywsOJpJAQ20Fwgcf+P/TDtvQ7zcsWsrJaglaQWDhOMsspQ==
+"@typescript-eslint/scope-manager@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.50.0.tgz#90b8a3b337ad2c52bbfe4eac38f9164614e40584"
+  integrity sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==
   dependencies:
-    "@typescript-eslint/types" "5.45.1"
-    "@typescript-eslint/visitor-keys" "5.45.1"
+    "@typescript-eslint/types" "5.50.0"
+    "@typescript-eslint/visitor-keys" "5.50.0"
 
-"@typescript-eslint/type-utils@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.1.tgz#cb7d300c3c95802cea9f87c7f8be363cf8f8538c"
-  integrity sha512-aosxFa+0CoYgYEl3aptLe1svP910DJq68nwEJzyQcrtRhC4BN0tJAvZGAe+D0tzjJmFXe+h4leSsiZhwBa2vrA==
+"@typescript-eslint/type-utils@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz#509d5cc9728d520008f7157b116a42c5460e7341"
+  integrity sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==
   dependencies:
-    "@typescript-eslint/typescript-estree" "5.45.1"
-    "@typescript-eslint/utils" "5.45.1"
+    "@typescript-eslint/typescript-estree" "5.50.0"
+    "@typescript-eslint/utils" "5.50.0"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.1.tgz#8e1883041cee23f1bb7e1343b0139f97f6a17c14"
-  integrity sha512-HEW3U0E5dLjUT+nk7b4lLbOherS1U4ap+b9pfu2oGsW3oPu7genRaY9dDv3nMczC1rbnRY2W/D7SN05wYoGImg==
+"@typescript-eslint/types@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.50.0.tgz#c461d3671a6bec6c2f41f38ed60bd87aa8a30093"
+  integrity sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==
 
-"@typescript-eslint/typescript-estree@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz#b3dc37f0c4f0fe73e09917fc735e6f96eabf9ba4"
-  integrity sha512-76NZpmpCzWVrrb0XmYEpbwOz/FENBi+5W7ipVXAsG3OoFrQKJMiaqsBMbvGRyLtPotGqUfcY7Ur8j0dksDJDng==
+"@typescript-eslint/typescript-estree@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.50.0.tgz#0b9b82975bdfa40db9a81fdabc7f93396867ea97"
+  integrity sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==
   dependencies:
-    "@typescript-eslint/types" "5.45.1"
-    "@typescript-eslint/visitor-keys" "5.45.1"
+    "@typescript-eslint/types" "5.50.0"
+    "@typescript-eslint/visitor-keys" "5.50.0"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.1.tgz#39610c98bde82c4792f2a858b29b7d0053448be2"
-  integrity sha512-rlbC5VZz68+yjAzQBc4I7KDYVzWG2X/OrqoZrMahYq3u8FFtmQYc+9rovo/7wlJH5kugJ+jQXV5pJMnofGmPRw==
+"@typescript-eslint/utils@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.50.0.tgz#807105f5ffb860644d30d201eefad7017b020816"
+  integrity sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==
   dependencies:
     "@types/json-schema" "^7.0.9"
     "@types/semver" "^7.3.12"
-    "@typescript-eslint/scope-manager" "5.45.1"
-    "@typescript-eslint/types" "5.45.1"
-    "@typescript-eslint/typescript-estree" "5.45.1"
+    "@typescript-eslint/scope-manager" "5.50.0"
+    "@typescript-eslint/types" "5.50.0"
+    "@typescript-eslint/typescript-estree" "5.50.0"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
     semver "^7.3.7"
 
-"@typescript-eslint/visitor-keys@5.45.1":
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz#204428430ad6a830d24c5ac87c71366a1cfe1948"
-  integrity sha512-cy9ln+6rmthYWjH9fmx+5FU/JDpjQb586++x2FZlveq7GdGuLLW9a2Jcst2TGekH82bXpfmRNSwP9tyEs6RjvQ==
+"@typescript-eslint/visitor-keys@5.50.0":
+  version "5.50.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.50.0.tgz#b752ffc143841f3d7bc57d6dd01ac5c40f8c4903"
+  integrity sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==
   dependencies:
-    "@typescript-eslint/types" "5.45.1"
+    "@typescript-eslint/types" "5.50.0"
     eslint-visitor-keys "^3.3.0"
 
 "@webassemblyjs/ast@1.11.1":

From 50734421d247875d983ae32b2dbbd0923d47e77a Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 27 Feb 2023 14:48:04 -0800
Subject: [PATCH 32/34] Use local @ember/test-helpers

---
 package.json |  2 +-
 yarn.lock    | 57 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/package.json b/package.json
index 218efffd..7ce1a784 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
     "@babel/core": "^7.20.5",
     "@babel/eslint-parser": "^7.19.1",
     "@ember/optional-features": "^2.0.0",
-    "@ember/test-helpers": "^2.9.3",
+    "@ember/test-helpers": "file:.yalc/@ember/test-helpers",
     "@embroider/test-setup": "^2.1.1",
     "@glimmer/component": "^1.1.2",
     "@tsconfig/ember": "^2.0.0",
diff --git a/yarn.lock b/yarn.lock
index 78395a01..4a4e4ce8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1100,19 +1100,17 @@
     mkdirp "^1.0.4"
     silent-error "^1.1.1"
 
-"@ember/test-helpers@^2.9.3":
-  version "2.9.3"
-  resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-2.9.3.tgz#c2a9d6ab1c367af92cf1a334f97eb19b8e06e6e1"
-  integrity sha512-ejVg4Dj+G/6zyLvQsYOvmGiOLU6AS94tY4ClaO1E2oVvjjtVJIRmVLFN61I+DuyBg9hS3cFoPjQRTZB9MRIbxQ==
+"@ember/test-helpers@file:.yalc/@ember/test-helpers":
+  version "2.9.0"
   dependencies:
     "@ember/test-waiters" "^3.0.0"
     "@embroider/macros" "^1.10.0"
     "@embroider/util" "^1.9.0"
     broccoli-debug "^0.6.5"
     broccoli-funnel "^3.0.8"
+    ember-auto-import "^2.5.0"
     ember-cli-babel "^7.26.11"
     ember-cli-htmlbars "^6.1.1"
-    ember-destroyable-polyfill "^2.0.3"
 
 "@ember/test-waiters@^3.0.0":
   version "3.0.2"
@@ -4057,6 +4055,42 @@ ember-auto-import@^2.4.1:
     typescript-memoize "^1.0.0-alpha.3"
     walk-sync "^3.0.0"
 
+ember-auto-import@^2.5.0:
+  version "2.6.1"
+  resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.1.tgz#bd8d434143bd411b99f4a8f32d8b58414d7da4f3"
+  integrity sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw==
+  dependencies:
+    "@babel/core" "^7.16.7"
+    "@babel/plugin-proposal-class-properties" "^7.16.7"
+    "@babel/plugin-proposal-decorators" "^7.16.7"
+    "@babel/preset-env" "^7.16.7"
+    "@embroider/macros" "^1.0.0"
+    "@embroider/shared-internals" "^2.0.0"
+    babel-loader "^8.0.6"
+    babel-plugin-ember-modules-api-polyfill "^3.5.0"
+    babel-plugin-htmlbars-inline-precompile "^5.2.1"
+    babel-plugin-syntax-dynamic-import "^6.18.0"
+    broccoli-debug "^0.6.4"
+    broccoli-funnel "^3.0.8"
+    broccoli-merge-trees "^4.2.0"
+    broccoli-plugin "^4.0.0"
+    broccoli-source "^3.0.0"
+    css-loader "^5.2.0"
+    debug "^4.3.1"
+    fs-extra "^10.0.0"
+    fs-tree-diff "^2.0.0"
+    handlebars "^4.3.1"
+    js-string-escape "^1.0.1"
+    lodash "^4.17.19"
+    mini-css-extract-plugin "^2.5.2"
+    parse5 "^6.0.1"
+    resolve "^1.20.0"
+    resolve-package-path "^4.0.3"
+    semver "^7.3.4"
+    style-loader "^2.0.0"
+    typescript-memoize "^1.0.0-alpha.3"
+    walk-sync "^3.0.0"
+
 ember-auto-import@^2.6.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.0.tgz#c7a2f799c9b700d74648cb02e35cf7bc1b44ac02"
@@ -4098,7 +4132,7 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.1:
   resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.1.tgz#5016b80cdef37036c4282eef2d863e1d73576879"
   integrity sha512-sKvOiPNHr5F/60NLd7SFzMpYPte/nnGkq/tMIfXejfKHIhaiIkYFqX8Z9UFTKWLLn+V7NOaby6niNPZUdvKCRw==
 
-ember-cli-babel@^7.0.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.22.1, ember-cli-babel@^7.23.1, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.6, ember-cli-babel@^7.7.3:
+ember-cli-babel@^7.0.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.23.1, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.6, ember-cli-babel@^7.7.3:
   version "7.26.11"
   resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.26.11.tgz#50da0fe4dcd99aada499843940fec75076249a9f"
   integrity sha512-JJYeYjiz/JTn34q7F5DSOjkkZqy8qwFOOxXfE6pe9yEJqWGu4qErKxlz8I22JoVEQ/aBUO+OcKTpmctvykM9YA==
@@ -4442,7 +4476,7 @@ ember-cli@~4.10.0:
     workerpool "^6.2.1"
     yam "^1.0.0"
 
-ember-compatibility-helpers@^1.0.2, ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.1:
+ember-compatibility-helpers@^1.0.2, ember-compatibility-helpers@^1.1.2:
   version "1.2.6"
   resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.6.tgz#603579ab2fb14be567ef944da3fc2d355f779cd8"
   integrity sha512-2UBUa5SAuPg8/kRVaiOfTwlXdeVweal1zdNPibwItrhR0IvPrXpaqwJDlEZnWKEoB+h33V0JIfiWleSG6hGkkA==
@@ -4453,15 +4487,6 @@ ember-compatibility-helpers@^1.0.2, ember-compatibility-helpers@^1.1.2, ember-co
     fs-extra "^9.1.0"
     semver "^5.4.1"
 
-ember-destroyable-polyfill@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz#1673ed66609a82268ef270a7d917ebd3647f11e1"
-  integrity sha512-TovtNqCumzyAiW0/OisSkkVK93xnVF4NRU6+FN0ubpfwEOpRrmM2RqDwXI6YAChCgSHON1cz0DfQStpA1Gjuuw==
-  dependencies:
-    ember-cli-babel "^7.22.1"
-    ember-cli-version-checker "^5.1.1"
-    ember-compatibility-helpers "^1.2.1"
-
 ember-disable-prototype-extensions@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/ember-disable-prototype-extensions/-/ember-disable-prototype-extensions-1.1.3.tgz#1969135217654b5e278f9fe2d9d4e49b5720329e"

From 55a235f5c277d1834eb18b42b52d0a38933e49ea Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 27 Feb 2023 14:50:50 -0800
Subject: [PATCH 33/34] Upgrade @typescript-eslint/*

---
 package.json |  4 +--
 yarn.lock    | 98 ++++++++++++++++++++++++++--------------------------
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/package.json b/package.json
index 7ce1a784..bc4ddee9 100644
--- a/package.json
+++ b/package.json
@@ -58,8 +58,8 @@
     "@tsconfig/ember": "^2.0.0",
     "@types/qunit": "^2.19.4",
     "@types/rsvp": "^4.0.4",
-    "@typescript-eslint/eslint-plugin": "^5.50.0",
-    "@typescript-eslint/parser": "^5.50.0",
+    "@typescript-eslint/eslint-plugin": "^5.54.0",
+    "@typescript-eslint/parser": "^5.54.0",
     "ember-angle-bracket-invocation-polyfill": "^3.0.2",
     "ember-cli": "~4.10.0",
     "ember-cli-dependency-checker": "^3.3.1",
diff --git a/yarn.lock b/yarn.lock
index 4a4e4ce8..a50faaca 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1740,14 +1740,14 @@
   resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
   integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
 
-"@typescript-eslint/eslint-plugin@^5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.50.0.tgz#fb48c31cadc853ffc1dc35373f56b5e2a8908fe9"
-  integrity sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==
-  dependencies:
-    "@typescript-eslint/scope-manager" "5.50.0"
-    "@typescript-eslint/type-utils" "5.50.0"
-    "@typescript-eslint/utils" "5.50.0"
+"@typescript-eslint/eslint-plugin@^5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz#2c821ad81b2c786d142279a8292090f77d1881f4"
+  integrity sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==
+  dependencies:
+    "@typescript-eslint/scope-manager" "5.54.0"
+    "@typescript-eslint/type-utils" "5.54.0"
+    "@typescript-eslint/utils" "5.54.0"
     debug "^4.3.4"
     grapheme-splitter "^1.0.4"
     ignore "^5.2.0"
@@ -1756,72 +1756,72 @@
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/parser@^5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.50.0.tgz#a33f44b2cc83d1b7176ec854fbecd55605b0b032"
-  integrity sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==
+"@typescript-eslint/parser@^5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.54.0.tgz#def186eb1b1dbd0439df0dacc44fb6d8d5c417fe"
+  integrity sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.50.0"
-    "@typescript-eslint/types" "5.50.0"
-    "@typescript-eslint/typescript-estree" "5.50.0"
+    "@typescript-eslint/scope-manager" "5.54.0"
+    "@typescript-eslint/types" "5.54.0"
+    "@typescript-eslint/typescript-estree" "5.54.0"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.50.0.tgz#90b8a3b337ad2c52bbfe4eac38f9164614e40584"
-  integrity sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==
+"@typescript-eslint/scope-manager@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz#74b28ac9a3fc8166f04e806c957adb8c1fd00536"
+  integrity sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==
   dependencies:
-    "@typescript-eslint/types" "5.50.0"
-    "@typescript-eslint/visitor-keys" "5.50.0"
+    "@typescript-eslint/types" "5.54.0"
+    "@typescript-eslint/visitor-keys" "5.54.0"
 
-"@typescript-eslint/type-utils@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz#509d5cc9728d520008f7157b116a42c5460e7341"
-  integrity sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==
+"@typescript-eslint/type-utils@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz#390717216eb61393a0cad2995da154b613ba7b26"
+  integrity sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==
   dependencies:
-    "@typescript-eslint/typescript-estree" "5.50.0"
-    "@typescript-eslint/utils" "5.50.0"
+    "@typescript-eslint/typescript-estree" "5.54.0"
+    "@typescript-eslint/utils" "5.54.0"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.50.0.tgz#c461d3671a6bec6c2f41f38ed60bd87aa8a30093"
-  integrity sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==
+"@typescript-eslint/types@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.54.0.tgz#7d519df01f50739254d89378e0dcac504cab2740"
+  integrity sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==
 
-"@typescript-eslint/typescript-estree@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.50.0.tgz#0b9b82975bdfa40db9a81fdabc7f93396867ea97"
-  integrity sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==
+"@typescript-eslint/typescript-estree@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz#f6f3440cabee8a43a0b25fa498213ebb61fdfe99"
+  integrity sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==
   dependencies:
-    "@typescript-eslint/types" "5.50.0"
-    "@typescript-eslint/visitor-keys" "5.50.0"
+    "@typescript-eslint/types" "5.54.0"
+    "@typescript-eslint/visitor-keys" "5.54.0"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.50.0.tgz#807105f5ffb860644d30d201eefad7017b020816"
-  integrity sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==
+"@typescript-eslint/utils@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.54.0.tgz#3db758aae078be7b54b8ea8ea4537ff6cd3fbc21"
+  integrity sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==
   dependencies:
     "@types/json-schema" "^7.0.9"
     "@types/semver" "^7.3.12"
-    "@typescript-eslint/scope-manager" "5.50.0"
-    "@typescript-eslint/types" "5.50.0"
-    "@typescript-eslint/typescript-estree" "5.50.0"
+    "@typescript-eslint/scope-manager" "5.54.0"
+    "@typescript-eslint/types" "5.54.0"
+    "@typescript-eslint/typescript-estree" "5.54.0"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
     semver "^7.3.7"
 
-"@typescript-eslint/visitor-keys@5.50.0":
-  version "5.50.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.50.0.tgz#b752ffc143841f3d7bc57d6dd01ac5c40f8c4903"
-  integrity sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==
+"@typescript-eslint/visitor-keys@5.54.0":
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz#846878afbf0cd67c19cfa8d75947383d4490db8f"
+  integrity sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==
   dependencies:
-    "@typescript-eslint/types" "5.50.0"
+    "@typescript-eslint/types" "5.54.0"
     eslint-visitor-keys "^3.3.0"
 
 "@webassemblyjs/ast@1.11.1":

From 2f420c5ca50c7cea6490c0ef4b2806204a7441b6 Mon Sep 17 00:00:00 2001
From: Krystan HuffMenne <krystan@tilde.io>
Date: Mon, 27 Feb 2023 15:02:12 -0800
Subject: [PATCH 34/34] Use @ember/test-helpers master and node 16

---
 package.json |  6 ++--
 yarn.lock    | 86 +++++-----------------------------------------------
 2 files changed, 10 insertions(+), 82 deletions(-)

diff --git a/package.json b/package.json
index bc4ddee9..babc0be4 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
     "@babel/core": "^7.20.5",
     "@babel/eslint-parser": "^7.19.1",
     "@ember/optional-features": "^2.0.0",
-    "@ember/test-helpers": "file:.yalc/@ember/test-helpers",
+    "@ember/test-helpers": "emberjs/ember-test-helpers#master",
     "@embroider/test-setup": "^2.1.1",
     "@glimmer/component": "^1.1.2",
     "@tsconfig/ember": "^2.0.0",
@@ -93,7 +93,7 @@
     "qunit": "^2.13.0"
   },
   "engines": {
-    "node": "14.* || 16.* || >= 18"
+    "node": "16.* || >= 18"
   },
   "publishConfig": {
     "registry": "https://registry.npmjs.org"
@@ -130,7 +130,7 @@
     }
   },
   "volta": {
-    "node": "14.19.1",
+    "node": "16.19.1",
     "yarn": "1.22.18"
   }
 }
diff --git a/yarn.lock b/yarn.lock
index a50faaca..60f7502d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1100,19 +1100,20 @@
     mkdirp "^1.0.4"
     silent-error "^1.1.1"
 
-"@ember/test-helpers@file:.yalc/@ember/test-helpers":
+"@ember/test-helpers@emberjs/ember-test-helpers#master":
   version "2.9.0"
+  resolved "https://codeload.github.com/emberjs/ember-test-helpers/tar.gz/22bd212187b14b63d448332e0755a2b9ea5cef31"
   dependencies:
-    "@ember/test-waiters" "^3.0.0"
+    "@ember/test-waiters" "^3.0.2"
     "@embroider/macros" "^1.10.0"
     "@embroider/util" "^1.9.0"
     broccoli-debug "^0.6.5"
     broccoli-funnel "^3.0.8"
-    ember-auto-import "^2.5.0"
+    ember-auto-import "^2.6.0"
     ember-cli-babel "^7.26.11"
-    ember-cli-htmlbars "^6.1.1"
+    ember-cli-htmlbars "^6.2.0"
 
-"@ember/test-waiters@^3.0.0":
+"@ember/test-waiters@^3.0.2":
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/@ember/test-waiters/-/test-waiters-3.0.2.tgz#5b950c580a1891ed1d4ee64f9c6bacf49a15ea6f"
   integrity sha512-H8Q3Xy9rlqhDKnQpwt2pzAYDouww4TZIGSI1pZJhM7mQIGufQKuB0ijzn/yugA6Z+bNdjYp1HioP8Y4hn2zazQ==
@@ -2355,7 +2356,7 @@ available-typed-arrays@^1.0.5:
   resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
   integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
 
-babel-import-util@^1.1.0, babel-import-util@^1.2.0:
+babel-import-util@^1.1.0:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-1.2.2.tgz#1027560e143a4a68b1758e71d4fadc661614e495"
   integrity sha512-8HgkHWt5WawRFukO30TuaL9EiDUOdvyKtDwLma4uBNeUSDbOO0/hiPfavrOWxSS6J6TKXfukWHZ3wiqZhJ8ONQ==
@@ -2403,16 +2404,6 @@ babel-plugin-ember-modules-api-polyfill@^3.5.0:
   dependencies:
     ember-rfc176-data "^0.3.17"
 
-babel-plugin-ember-template-compilation@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-ember-template-compilation/-/babel-plugin-ember-template-compilation-1.0.2.tgz#e0695b8ad5a8fe6b2cbdff1eadb01cf402731ad6"
-  integrity sha512-4HBMksmlYsWEf/C/n3uW5rkBRbUp4FNaspzdQTAHgLbfCJnkLze8R6i6sUSge48y/Wne7mx+vcImI1o6rlUwXQ==
-  dependencies:
-    babel-import-util "^1.2.0"
-    line-column "^1.0.2"
-    magic-string "^0.26.0"
-    string.prototype.matchall "^4.0.5"
-
 babel-plugin-ember-template-compilation@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-ember-template-compilation/-/babel-plugin-ember-template-compilation-2.0.0.tgz#41d895874ba6119dd461f61993c16d1154bf8a57"
@@ -4055,42 +4046,6 @@ ember-auto-import@^2.4.1:
     typescript-memoize "^1.0.0-alpha.3"
     walk-sync "^3.0.0"
 
-ember-auto-import@^2.5.0:
-  version "2.6.1"
-  resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.1.tgz#bd8d434143bd411b99f4a8f32d8b58414d7da4f3"
-  integrity sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw==
-  dependencies:
-    "@babel/core" "^7.16.7"
-    "@babel/plugin-proposal-class-properties" "^7.16.7"
-    "@babel/plugin-proposal-decorators" "^7.16.7"
-    "@babel/preset-env" "^7.16.7"
-    "@embroider/macros" "^1.0.0"
-    "@embroider/shared-internals" "^2.0.0"
-    babel-loader "^8.0.6"
-    babel-plugin-ember-modules-api-polyfill "^3.5.0"
-    babel-plugin-htmlbars-inline-precompile "^5.2.1"
-    babel-plugin-syntax-dynamic-import "^6.18.0"
-    broccoli-debug "^0.6.4"
-    broccoli-funnel "^3.0.8"
-    broccoli-merge-trees "^4.2.0"
-    broccoli-plugin "^4.0.0"
-    broccoli-source "^3.0.0"
-    css-loader "^5.2.0"
-    debug "^4.3.1"
-    fs-extra "^10.0.0"
-    fs-tree-diff "^2.0.0"
-    handlebars "^4.3.1"
-    js-string-escape "^1.0.1"
-    lodash "^4.17.19"
-    mini-css-extract-plugin "^2.5.2"
-    parse5 "^6.0.1"
-    resolve "^1.20.0"
-    resolve-package-path "^4.0.3"
-    semver "^7.3.4"
-    style-loader "^2.0.0"
-    typescript-memoize "^1.0.0-alpha.3"
-    walk-sync "^3.0.0"
-
 ember-auto-import@^2.6.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.0.tgz#c7a2f799c9b700d74648cb02e35cf7bc1b44ac02"
@@ -4184,26 +4139,6 @@ ember-cli-get-component-path-option@^1.0.0:
   resolved "https://registry.yarnpkg.com/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz#0d7b595559e2f9050abed804f1d8eff1b08bc771"
   integrity sha512-k47TDwcJ2zPideBCZE8sCiShSxQSpebY2BHcX2DdipMmBox5gsfyVrbKJWIHeSTTKyEUgmBIvQkqTOozEziCZA==
 
-ember-cli-htmlbars@^6.1.1:
-  version "6.1.1"
-  resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-6.1.1.tgz#f5b588572a5d18ad087560122b8dabc90145173d"
-  integrity sha512-DKf2rjzIVw9zWCuFsBGJScrgf5Mz7dSg08Cq+FWFYIxnpssINUbNUoB0NHWnUJK4QqCvaExOyOmjm0kO455CPg==
-  dependencies:
-    "@ember/edition-utils" "^1.2.0"
-    babel-plugin-ember-template-compilation "^1.0.0"
-    babel-plugin-htmlbars-inline-precompile "^5.3.0"
-    broccoli-debug "^0.6.5"
-    broccoli-persistent-filter "^3.1.2"
-    broccoli-plugin "^4.0.3"
-    ember-cli-version-checker "^5.1.2"
-    fs-tree-diff "^2.0.1"
-    hash-for-dep "^1.5.1"
-    heimdalljs-logger "^0.1.10"
-    js-string-escape "^1.0.1"
-    semver "^7.3.4"
-    silent-error "^1.1.1"
-    walk-sync "^2.2.0"
-
 ember-cli-htmlbars@^6.2.0:
   version "6.2.0"
   resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-6.2.0.tgz#18ec48ee1c93f9eed862a64eb24a9d14604f1dfc"
@@ -7542,13 +7477,6 @@ magic-string@^0.25.7:
   dependencies:
     sourcemap-codec "^1.4.8"
 
-magic-string@^0.26.0:
-  version "0.26.7"
-  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f"
-  integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==
-  dependencies:
-    sourcemap-codec "^1.4.8"
-
 make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"