diff --git a/packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap b/packages/expect/src/__tests__/__snapshots__/assertionCounts.test.ts.snap
similarity index 100%
rename from packages/expect/src/__tests__/__snapshots__/assertionCounts.test.js.snap
rename to packages/expect/src/__tests__/__snapshots__/assertionCounts.test.ts.snap
diff --git a/packages/expect/src/__tests__/__snapshots__/extend.test.js.snap b/packages/expect/src/__tests__/__snapshots__/extend.test.ts.snap
similarity index 100%
rename from packages/expect/src/__tests__/__snapshots__/extend.test.js.snap
rename to packages/expect/src/__tests__/__snapshots__/extend.test.ts.snap
diff --git a/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/spyMatchers.test.ts.snap
similarity index 100%
rename from packages/expect/src/__tests__/__snapshots__/spyMatchers.test.js.snap
rename to packages/expect/src/__tests__/__snapshots__/spyMatchers.test.ts.snap
diff --git a/packages/expect/src/__tests__/assertionCounts.test.js b/packages/expect/src/__tests__/assertionCounts.test.ts
similarity index 90%
rename from packages/expect/src/__tests__/assertionCounts.test.js
rename to packages/expect/src/__tests__/assertionCounts.test.ts
index ce9c31d3fff4..672edbca6756 100644
--- a/packages/expect/src/__tests__/assertionCounts.test.js
+++ b/packages/expect/src/__tests__/assertionCounts.test.ts
@@ -6,10 +6,8 @@
  *
  */
 
-'use strict';
-
-const {alignedAnsiStyleSerializer} = require('@jest/test-utils');
-const jestExpect = require('../');
+import {alignedAnsiStyleSerializer} from '@jest/test-utils';
+import jestExpect from '../';
 
 expect.addSnapshotSerializer(alignedAnsiStyleSerializer);
 
diff --git a/packages/expect/src/__tests__/extend.test.js b/packages/expect/src/__tests__/extend.test.ts
similarity index 86%
rename from packages/expect/src/__tests__/extend.test.js
rename to packages/expect/src/__tests__/extend.test.ts
index 11b915332fee..fb9e30540c8d 100644
--- a/packages/expect/src/__tests__/extend.test.js
+++ b/packages/expect/src/__tests__/extend.test.ts
@@ -6,16 +6,16 @@
  *
  */
 
-const matcherUtils = require('jest-matcher-utils');
-const {alignedAnsiStyleSerializer} = require('@jest/test-utils');
-const {iterableEquality, subsetEquality} = require('../utils');
-const {equals} = require('../jasmineUtils');
-const jestExpect = require('../');
+import * as matcherUtils from 'jest-matcher-utils';
+import {alignedAnsiStyleSerializer} from '@jest/test-utils';
+import {iterableEquality, subsetEquality} from '../utils';
+import {equals} from '../jasmineUtils';
+import jestExpect from '../';
 
 expect.addSnapshotSerializer(alignedAnsiStyleSerializer);
 
 jestExpect.extend({
-  toBeDivisibleBy(actual, expected) {
+  toBeDivisibleBy(actual: number, expected: number) {
     const pass = actual % expected === 0;
     const message = pass
       ? () => `expected ${actual} not to be divisible by ${expected}`
@@ -23,13 +23,14 @@ jestExpect.extend({
 
     return {message, pass};
   },
-  toBeSymbol(actual, expected) {
+  toBeSymbol(actual: symbol, expected: symbol) {
     const pass = actual === expected;
-    const message = () => `expected ${actual} to be Symbol ${expected}`;
+    const message = () =>
+      `expected ${actual.toString()} to be Symbol ${expected.toString()}`;
 
     return {message, pass};
   },
-  toBeWithinRange(actual, floor, ceiling) {
+  toBeWithinRange(actual: number, floor: number, ceiling: number) {
     const pass = actual >= floor && actual <= ceiling;
     const message = pass
       ? () => `expected ${actual} not to be within range ${floor} - ${ceiling}`
@@ -60,7 +61,7 @@ it('is available globally when matcher is variadic', () => {
 
 it('exposes matcherUtils in context', () => {
   jestExpect.extend({
-    _shouldNotError(actual, expected) {
+    _shouldNotError(_actual: unknown, _expected: unknown) {
       const pass = this.equals(
         this.utils,
         Object.assign(matcherUtils, {
@@ -81,7 +82,7 @@ it('exposes matcherUtils in context', () => {
 
 it('is ok if there is no message specified', () => {
   jestExpect.extend({
-    toFailWithoutMessage(expected) {
+    toFailWithoutMessage(_expected: unknown) {
       return {pass: false};
     },
   });
diff --git a/packages/expect/src/__tests__/fakeChalk.test.js b/packages/expect/src/__tests__/fakeChalk.test.ts
similarity index 97%
rename from packages/expect/src/__tests__/fakeChalk.test.js
rename to packages/expect/src/__tests__/fakeChalk.test.ts
index e8dd2ea5c340..4fbb6cebef2f 100644
--- a/packages/expect/src/__tests__/fakeChalk.test.js
+++ b/packages/expect/src/__tests__/fakeChalk.test.ts
@@ -4,7 +4,6 @@
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
  */
-'use strict';
 
 const fakeChalk = jest.requireActual('../fakeChalk');
 
diff --git a/packages/expect/src/__tests__/isError.test.js b/packages/expect/src/__tests__/isError.test.ts
similarity index 82%
rename from packages/expect/src/__tests__/isError.test.js
rename to packages/expect/src/__tests__/isError.test.ts
index 44192188aa51..bb6a77c47e6d 100644
--- a/packages/expect/src/__tests__/isError.test.js
+++ b/packages/expect/src/__tests__/isError.test.ts
@@ -13,14 +13,16 @@ import {isError} from '../utils';
 
 // Copied from https://github.com/graingert/angular.js/blob/a43574052e9775cbc1d7dd8a086752c979b0f020/test/AngularSpec.js#L1883
 describe('isError', () => {
-  function testErrorFromDifferentContext(createError) {
+  function testErrorFromDifferentContext(
+    createError: (win: Window | null) => Error,
+  ) {
     const iframe = document.createElement('iframe');
     document.body.appendChild(iframe);
     try {
       const error = createError(iframe.contentWindow);
       expect(isError(error)).toBe(true);
     } finally {
-      iframe.parentElement.removeChild(iframe);
+      iframe.parentElement!.removeChild(iframe);
     }
   }
 
@@ -34,11 +36,11 @@ describe('isError', () => {
   });
 
   it('should detect errors from another context', () => {
-    testErrorFromDifferentContext(win => new win.Error());
+    testErrorFromDifferentContext((win: Window) => new win.Error());
   });
 
   it('should detect DOMException errors from another context', () => {
-    testErrorFromDifferentContext(win => {
+    testErrorFromDifferentContext((win: Window) => {
       try {
         win.document.querySelectorAll('');
       } catch (e) {
diff --git a/packages/expect/src/__tests__/spyMatchers.test.js b/packages/expect/src/__tests__/spyMatchers.test.ts
similarity index 96%
rename from packages/expect/src/__tests__/spyMatchers.test.js
rename to packages/expect/src/__tests__/spyMatchers.test.ts
index 1c3a5c956e65..e819b2efcfb9 100644
--- a/packages/expect/src/__tests__/spyMatchers.test.js
+++ b/packages/expect/src/__tests__/spyMatchers.test.ts
@@ -5,14 +5,14 @@
  * LICENSE file in the root directory of this source tree.
  */
 
-const Immutable = require('immutable');
-const {alignedAnsiStyleSerializer} = require('@jest/test-utils');
-const jestExpect = require('../');
+import * as Immutable from 'immutable';
+import {alignedAnsiStyleSerializer} from '@jest/test-utils';
+import jestExpect from '../';
 
 expect.addSnapshotSerializer(alignedAnsiStyleSerializer);
 
 // Given a Jest mock function, return a minimal mock of a Jasmine spy.
-const createSpy = fn => {
+const createSpy = (fn: jest.Mock) => {
   const spy = function () {};
 
   spy.calls = {
@@ -177,7 +177,10 @@ const createSpy = fn => {
   'toBeCalledWith',
   'toHaveBeenCalledWith',
 ].forEach(calledWith => {
-  const caller = function (callee, ...args) {
+  const caller = function (
+    callee: (...a: Array<unknown>) => void,
+    ...args: any
+  ) {
     if (
       calledWith === 'nthCalledWith' ||
       calledWith === 'toHaveBeenNthCalledWith'
@@ -295,8 +298,8 @@ const createSpy = fn => {
 
     test(`works with Immutable.js objects`, () => {
       const fn = jest.fn();
-      const directlyCreated = new Immutable.Map([['a', {b: 'c'}]]);
-      const indirectlyCreated = new Immutable.Map().set('a', {b: 'c'});
+      const directlyCreated = Immutable.Map([['a', {b: 'c'}]]);
+      const indirectlyCreated = Immutable.Map().set('a', {b: 'c'});
       fn(directlyCreated, indirectlyCreated);
 
       caller(jestExpect(fn)[calledWith], indirectlyCreated, directlyCreated);
@@ -534,7 +537,7 @@ const createSpy = fn => {
 
     test(`incomplete recursive calls are handled properly`, () => {
       // sums up all integers from 0 -> value, using recursion
-      const fn = jest.fn(value => {
+      const fn: jest.Mock = jest.fn(value => {
         if (value === 0) {
           // Before returning from the base case of recursion, none of the
           // calls have returned yet.
@@ -703,7 +706,7 @@ const createSpy = fn => {
 
     test(`incomplete recursive calls are handled properly`, () => {
       // sums up all integers from 0 -> value, using recursion
-      const fn = jest.fn(value => {
+      const fn: jest.Mock = jest.fn(value => {
         if (value === 0) {
           return 0;
         } else {
@@ -734,7 +737,10 @@ const createSpy = fn => {
   'toReturnWith',
   'toHaveReturnedWith',
 ].forEach(returnedWith => {
-  const caller = function (callee, ...args) {
+  const caller = function (
+    callee: (...a: Array<unknown>) => void,
+    ...args: any
+  ) {
     if (
       returnedWith === 'nthReturnedWith' ||
       returnedWith === 'toHaveNthReturnedWith'
@@ -850,7 +856,7 @@ const createSpy = fn => {
     });
 
     test(`works with Immutable.js objects directly created`, () => {
-      const directlyCreated = new Immutable.Map([['a', {b: 'c'}]]);
+      const directlyCreated = Immutable.Map([['a', {b: 'c'}]]);
       const fn = jest.fn(() => directlyCreated);
       fn();
 
@@ -862,7 +868,7 @@ const createSpy = fn => {
     });
 
     test(`works with Immutable.js objects indirectly created`, () => {
-      const indirectlyCreated = new Immutable.Map().set('a', {b: 'c'});
+      const indirectlyCreated = Immutable.Map().set('a', {b: 'c'});
       const fn = jest.fn(() => indirectlyCreated);
       fn();
 
@@ -944,7 +950,7 @@ const createSpy = fn => {
 
         test(`incomplete recursive calls are handled properly`, () => {
           // sums up all integers from 0 -> value, using recursion
-          const fn = jest.fn(value => {
+          const fn: jest.Mock = jest.fn(value => {
             if (value === 0) {
               // Before returning from the base case of recursion, none of the
               // calls have returned yet.
@@ -1032,7 +1038,7 @@ const createSpy = fn => {
         });
 
         test('positive throw matcher error for n that is not integer', async () => {
-          const fn = jest.fn(() => 'foo');
+          const fn: jest.Mock = jest.fn(() => 'foo');
           fn('foo');
 
           expect(() => {
@@ -1041,7 +1047,7 @@ const createSpy = fn => {
         });
 
         test('negative throw matcher error for n that is not number', async () => {
-          const fn = jest.fn(() => 'foo');
+          const fn: jest.Mock = jest.fn(() => 'foo');
           fn('foo');
 
           expect(() => {
@@ -1051,7 +1057,7 @@ const createSpy = fn => {
 
         test(`incomplete recursive calls are handled properly`, () => {
           // sums up all integers from 0 -> value, using recursion
-          const fn = jest.fn(value => {
+          const fn: jest.Mock = jest.fn(value => {
             if (value === 0) {
               return 0;
             } else {
@@ -1108,7 +1114,7 @@ const createSpy = fn => {
 
         test(`incomplete recursive calls are handled properly`, () => {
           // sums up all integers from 0 -> value, using recursion
-          const fn = jest.fn(value => {
+          const fn: jest.Mock = jest.fn(value => {
             if (value === 0) {
               // Before returning from the base case of recursion, none of the
               // calls have returned yet.
diff --git a/packages/expect/src/__tests__/stacktrace.test.js b/packages/expect/src/__tests__/stacktrace.test.ts
similarity index 74%
rename from packages/expect/src/__tests__/stacktrace.test.js
rename to packages/expect/src/__tests__/stacktrace.test.ts
index a2143257945e..47cb0cfff155 100644
--- a/packages/expect/src/__tests__/stacktrace.test.js
+++ b/packages/expect/src/__tests__/stacktrace.test.ts
@@ -6,10 +6,10 @@
  *
  */
 
-const jestExpect = require('../');
+import jestExpect from '../';
 
 jestExpect.extend({
-  toCustomMatch(callback, expectation) {
+  toCustomMatch(callback: () => unknown, expectation: unknown) {
     const actual = callback();
 
     if (actual !== expectation) {
@@ -21,7 +21,7 @@ jestExpect.extend({
 
     return {pass: true};
   },
-  toMatchPredicate(received, argument) {
+  toMatchPredicate(received: unknown, argument: (a: unknown) => void) {
     argument(received);
     return {
       message: () => '',
@@ -34,17 +34,17 @@ it('stack trace points to correct location when using matchers', () => {
   try {
     jestExpect(true).toBe(false);
   } catch (error) {
-    expect(error.stack).toContain('stacktrace.test.js:35');
+    expect(error.stack).toContain('stacktrace.test.ts:35');
   }
 });
 
 it('stack trace points to correct location when using nested matchers', () => {
   try {
-    jestExpect(true).toMatchPredicate(value => {
+    jestExpect(true).toMatchPredicate((value: unknown) => {
       jestExpect(value).toBe(false);
     });
   } catch (error) {
-    expect(error.stack).toContain('stacktrace.test.js:44');
+    expect(error.stack).toContain('stacktrace.test.ts:44');
   }
 });
 
@@ -60,6 +60,6 @@ it('stack trace points to correct location when throwing from a custom matcher',
       foo();
     }).toCustomMatch('bar');
   } catch (error) {
-    expect(error.stack).toContain('stacktrace.test.js:57');
+    expect(error.stack).toContain('stacktrace.test.ts:57');
   }
 });
diff --git a/packages/expect/src/__tests__/symbolInObjects.test.js b/packages/expect/src/__tests__/symbolInObjects.test.ts
similarity index 98%
rename from packages/expect/src/__tests__/symbolInObjects.test.js
rename to packages/expect/src/__tests__/symbolInObjects.test.ts
index 97a85417fc00..352208adbf59 100644
--- a/packages/expect/src/__tests__/symbolInObjects.test.js
+++ b/packages/expect/src/__tests__/symbolInObjects.test.ts
@@ -6,8 +6,6 @@
  *
  */
 
-'use strict';
-
 describe('Symbol in objects', () => {
   test('should compare objects with Symbol keys', () => {
     const sym = Symbol('foo');
diff --git a/packages/expect/src/__tests__/toEqual-dom.test.js b/packages/expect/src/__tests__/toEqual-dom.test.ts
similarity index 96%
rename from packages/expect/src/__tests__/toEqual-dom.test.js
rename to packages/expect/src/__tests__/toEqual-dom.test.ts
index ed1f32ea6be4..605c7e628537 100644
--- a/packages/expect/src/__tests__/toEqual-dom.test.js
+++ b/packages/expect/src/__tests__/toEqual-dom.test.ts
@@ -12,18 +12,18 @@ describe('toEqual', () => {
   describe('duck type', () => {
     // https://github.com/facebook/jest/issues/7786
 
-    const createElement = (name, ...childNodes) => ({
+    const createElement = (name: string, ...childNodes: Array<unknown>) => ({
       childNodes,
       nodeType: 1,
       tagName: name.toUpperCase(),
     });
 
-    const createTextNode = data => ({
+    const createTextNode = (data: unknown) => ({
       data,
       nodeType: 3,
     });
 
-    const createDocumentFragment = (...children) => ({
+    const createDocumentFragment = (...children: Array<unknown>) => ({
       children,
       nodeType: 11,
     });
diff --git a/packages/expect/src/__tests__/utils.test.js b/packages/expect/src/__tests__/utils.test.ts
similarity index 90%
rename from packages/expect/src/__tests__/utils.test.js
rename to packages/expect/src/__tests__/utils.test.ts
index 0eb4bdca4659..d5b31b84a16b 100644
--- a/packages/expect/src/__tests__/utils.test.js
+++ b/packages/expect/src/__tests__/utils.test.ts
@@ -6,17 +6,15 @@
  *
  */
 
-'use strict';
-
-const {stringify} = require('jest-matcher-utils');
-const {
+import {stringify} from 'jest-matcher-utils';
+import {
   emptyObject,
   getObjectSubset,
   getPath,
   hasOwnProperty,
-  subsetEquality,
   iterableEquality,
-} = require('../utils');
+  subsetEquality,
+} from '../utils';
 
 describe('getPath()', () => {
   test('property exists', () => {
@@ -79,6 +77,7 @@ describe('getPath()', () => {
 
   test('property is inherited', () => {
     class A {}
+    // @ts-expect-error
     A.prototype.a = 'a';
 
     expect(getPath(new A(), 'a')).toEqual({
@@ -120,7 +119,7 @@ describe('hasOwnProperty', () => {
 
   it('does not inherit setter from class', () => {
     class MyClass {
-      set key(value) {}
+      set key(_value: unknown) {}
     }
     expect(hasOwnProperty(new MyClass(), 'key')).toBe(false);
   });
@@ -135,6 +134,7 @@ describe('hasOwnProperty', () => {
   it('does not inherit property from constructor prototype', () => {
     function MyClass() {}
     MyClass.prototype.key = 'value';
+    // @ts-expect-error
     expect(hasOwnProperty(new MyClass(), 'key')).toBe(false);
   });
 
@@ -208,18 +208,20 @@ describe('getObjectSubset', () => {
 
   describe('calculating subsets of objects with circular references', () => {
     test('simple circular references', () => {
+      type CircularObj = {a?: string; b?: string; ref?: unknown};
+
       const nonCircularObj = {a: 'world', b: 'something'};
 
-      const circularObjA = {a: 'hello'};
+      const circularObjA: CircularObj = {a: 'hello'};
       circularObjA.ref = circularObjA;
 
-      const circularObjB = {a: 'world'};
+      const circularObjB: CircularObj = {a: 'world'};
       circularObjB.ref = circularObjB;
 
-      const primitiveInsteadOfRef = {b: 'something'};
+      const primitiveInsteadOfRef: CircularObj = {b: 'something'};
       primitiveInsteadOfRef.ref = 'not a ref';
 
-      const nonCircularRef = {b: 'something'};
+      const nonCircularRef: CircularObj = {b: 'something'};
       nonCircularRef.ref = {};
 
       expect(getObjectSubset(circularObjA, nonCircularObj)).toEqual({
@@ -240,18 +242,20 @@ describe('getObjectSubset', () => {
     });
 
     test('transitive circular references', () => {
+      type CircularObj = {a?: string; nestedObj?: unknown};
+
       const nonCircularObj = {a: 'world', b: 'something'};
 
-      const transitiveCircularObjA = {a: 'hello'};
+      const transitiveCircularObjA: CircularObj = {a: 'hello'};
       transitiveCircularObjA.nestedObj = {parentObj: transitiveCircularObjA};
 
-      const transitiveCircularObjB = {a: 'world'};
+      const transitiveCircularObjB: CircularObj = {a: 'world'};
       transitiveCircularObjB.nestedObj = {parentObj: transitiveCircularObjB};
 
-      const primitiveInsteadOfRef = {};
+      const primitiveInsteadOfRef: CircularObj = {};
       primitiveInsteadOfRef.nestedObj = {otherProp: 'not the parent ref'};
 
-      const nonCircularRef = {};
+      const nonCircularRef: CircularObj = {};
       nonCircularRef.nestedObj = {otherProp: {}};
 
       expect(getObjectSubset(transitiveCircularObjA, nonCircularObj)).toEqual({
@@ -314,16 +318,18 @@ describe('subsetEquality()', () => {
 
   describe('matching subsets with circular references', () => {
     test('simple circular references', () => {
-      const circularObjA1 = {a: 'hello'};
+      type CircularObj = {a?: string; ref?: unknown};
+
+      const circularObjA1: CircularObj = {a: 'hello'};
       circularObjA1.ref = circularObjA1;
 
-      const circularObjA2 = {a: 'hello'};
+      const circularObjA2: CircularObj = {a: 'hello'};
       circularObjA2.ref = circularObjA2;
 
-      const circularObjB = {a: 'world'};
+      const circularObjB: CircularObj = {a: 'world'};
       circularObjB.ref = circularObjB;
 
-      const primitiveInsteadOfRef = {};
+      const primitiveInsteadOfRef: CircularObj = {};
       primitiveInsteadOfRef.ref = 'not a ref';
 
       expect(subsetEquality(circularObjA1, {})).toBe(true);
@@ -347,21 +353,22 @@ describe('subsetEquality()', () => {
     });
 
     test('transitive circular references', () => {
-      const transitiveCircularObjA1 = {a: 'hello'};
+      type CircularObj = {a: string; nestedObj?: unknown};
+
+      const transitiveCircularObjA1: CircularObj = {a: 'hello'};
       transitiveCircularObjA1.nestedObj = {parentObj: transitiveCircularObjA1};
 
-      const transitiveCircularObjA2 = {a: 'hello'};
+      const transitiveCircularObjA2: CircularObj = {a: 'hello'};
       transitiveCircularObjA2.nestedObj = {
         parentObj: transitiveCircularObjA2,
       };
 
-      const transitiveCircularObjB = {a: 'world'};
+      const transitiveCircularObjB: CircularObj = {a: 'world'};
       transitiveCircularObjB.nestedObj = {
         parentObj: transitiveCircularObjB,
       };
 
-      const primitiveInsteadOfRef = {};
-      primitiveInsteadOfRef.nestedObj = {
+      const primitiveInsteadOfRef = {
         parentObj: 'not the parent ref',
       };