diff --git a/CHANGELOG.md b/CHANGELOG.md index cd8e4b88e90f..6be6ed5729f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Chore & Maintenance +- `[*]` Replace `any`s with `unknown`s ([#9626](https://github.com/facebook/jest/pull/9626)) - `[@jest/transform]` Expose type `CacheKeyOptions` for `getCacheKey` ([#9762](https://github.com/facebook/jest/pull/9762)) ### Performance diff --git a/packages/expect/src/matchers.ts b/packages/expect/src/matchers.ts index 73b571f49d73..26c7725e2de1 100644 --- a/packages/expect/src/matchers.ts +++ b/packages/expect/src/matchers.ts @@ -64,7 +64,7 @@ const toStrictEqualTesters = [ type ContainIterable = | Array | Set - | NodeListOf + | NodeListOf | DOMTokenList | HTMLCollectionOf; @@ -630,7 +630,7 @@ const matchers: MatchersObject = { if ( typeof received !== 'string' && - (!received || typeof received.length !== 'number') + (typeof received !== 'object' || typeof received.length !== 'number') ) { throw new Error( matcherErrorMessage( diff --git a/packages/expect/src/toThrowMatchers.ts b/packages/expect/src/toThrowMatchers.ts index 63cc3706264f..b9dc7b5a2735 100644 --- a/packages/expect/src/toThrowMatchers.ts +++ b/packages/expect/src/toThrowMatchers.ts @@ -223,7 +223,7 @@ const toThrowExpectedObject = ( matcherName: string, options: MatcherHintOptions, thrown: Thrown | null, - expected: any, + expected: Error, ): SyncExpectationResult => { const pass = thrown !== null && thrown.message === expected.message; diff --git a/packages/jest-cli/src/cli/index.ts b/packages/jest-cli/src/cli/index.ts index 91a41aef85d9..06fb3bf4d31a 100644 --- a/packages/jest-cli/src/cli/index.ts +++ b/packages/jest-cli/src/cli/index.ts @@ -74,12 +74,15 @@ export const buildArgv = (maybeArgv?: Array): Config.Argv => { ); // strip dashed args - return Object.keys(argv).reduce((result, key) => { - if (!key.includes('-')) { - result[key] = argv[key]; - } - return result; - }, {} as Config.Argv); + return Object.keys(argv).reduce( + (result, key) => { + if (!key.includes('-')) { + result[key] = argv[key]; + } + return result; + }, + {$0: argv.$0, _: argv._}, + ); }; const getProjectListFromCLIArgs = ( diff --git a/packages/jest-config/src/ReporterValidationErrors.ts b/packages/jest-config/src/ReporterValidationErrors.ts index 9a458913ef25..271d810ea117 100644 --- a/packages/jest-config/src/ReporterValidationErrors.ts +++ b/packages/jest-config/src/ReporterValidationErrors.ts @@ -39,7 +39,7 @@ export function createArrayReporterError( arrayReporter: Config.ReporterConfig, reporterIndex: number, valueIndex: number, - value: string | Record, + value: string | Record, expectedType: string, valueName: string, ): ValidationError { diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 4fbf26ffc57e..fb56b9864e26 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -746,14 +746,14 @@ export default function normalize( ? _replaceRootDirTags(options.rootDir, project) : project, ) - .reduce((projects, project) => { + .reduce>((projects, project) => { // Project can be specified as globs. If a glob matches any files, // We expand it to these paths. If not, we keep the original path // for the future resolution. const globMatches = typeof project === 'string' ? glob(project) : []; return projects.concat(globMatches.length ? globMatches : project); - }, [] as Array); + }, []); break; case 'moduleDirectories': case 'testMatch': diff --git a/packages/jest-core/src/FailedTestsCache.ts b/packages/jest-core/src/FailedTestsCache.ts index dcb0b370ff11..0bcda8046500 100644 --- a/packages/jest-core/src/FailedTestsCache.ts +++ b/packages/jest-core/src/FailedTestsCache.ts @@ -29,10 +29,10 @@ export default class FailedTestsCache { .reduce((suiteMap, testResult) => { suiteMap[testResult.testFilePath] = testResult.testResults .filter(test => test.status === 'failed') - .reduce((testMap, test) => { + .reduce<{[name: string]: true}>((testMap, test) => { testMap[test.fullName] = true; return testMap; - }, {} as {[name: string]: true}); + }, {}); return suiteMap; }, {}); diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 49c74bf981bc..b1f60c3878b4 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -158,9 +158,11 @@ export default function watch( if (globalConfig.watchPlugins != null) { const watchPluginKeys: WatchPluginKeysMap = new Map(); for (const plugin of watchPlugins) { - const reservedInfo = - RESERVED_KEY_PLUGINS.get(plugin.constructor as WatchPluginClass) || - ({} as ReservedInfo); + const reservedInfo: Pick< + ReservedInfo, + 'forbiddenOverwriteMessage' | 'key' + > = + RESERVED_KEY_PLUGINS.get(plugin.constructor as WatchPluginClass) || {}; const key = reservedInfo.key || getPluginKey(plugin, globalConfig); if (!key) { continue; diff --git a/packages/jest-docblock/src/index.ts b/packages/jest-docblock/src/index.ts index c4d416c7817b..0cee7d16c863 100644 --- a/packages/jest-docblock/src/index.ts +++ b/packages/jest-docblock/src/index.ts @@ -18,6 +18,7 @@ const ltrimNewlineRe = /^(\r?\n)+/; const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g; const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; const stringStartRe = /(\r?\n|^) *\* ?/g; +const STRING_ARRAY: ReadonlyArray = []; export function extract(contents: string): string { const match = contents.match(docblockRe); @@ -65,10 +66,7 @@ export function parseWithComments( typeof result[match[1]] === 'string' || Array.isArray(result[match[1]]) ) { - result[match[1]] = ([] as Array).concat( - result[match[1]], - nextPragma, - ); + result[match[1]] = STRING_ARRAY.concat(result[match[1]], nextPragma); } else { result[match[1]] = nextPragma; } @@ -123,7 +121,7 @@ export function print({ } function printKeyValues(key: string, valueOrArray: string | Array) { - return ([] as Array) - .concat(valueOrArray) - .map(value => `@${key} ${value}`.trim()); + return STRING_ARRAY.concat(valueOrArray).map(value => + `@${key} ${value}`.trim(), + ); } diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 5fcd828a3bc7..f425d4ed1607 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -372,7 +372,7 @@ export default class FakeTimers { const promisifiableFakeSetTimeout = fn(this._fakeSetTimeout.bind(this)); promisifiableFakeSetTimeout[util.promisify.custom] = ( delay?: number, - arg?: any, + arg?: unknown, ) => new Promise(resolve => promisifiableFakeSetTimeout(resolve, delay, arg)); diff --git a/packages/jest-haste-map/src/ModuleMap.ts b/packages/jest-haste-map/src/ModuleMap.ts index 2b7e3be6655d..ce1e2b31f142 100644 --- a/packages/jest-haste-map/src/ModuleMap.ts +++ b/packages/jest-haste-map/src/ModuleMap.ts @@ -18,7 +18,7 @@ import type { import * as fastPath from './lib/fast_path'; import H from './constants'; -const EMPTY_OBJ = {} as Record; +const EMPTY_OBJ: Record = {}; const EMPTY_MAP = new Map(); type ValueType = T extends Map ? V : never; diff --git a/packages/jest-jasmine2/src/jasmine/Env.ts b/packages/jest-jasmine2/src/jasmine/Env.ts index ec6589240a4e..48e6b82fd4b4 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.ts +++ b/packages/jest-jasmine2/src/jasmine/Env.ts @@ -66,7 +66,7 @@ export default function (j$: Jasmine) { ) => Promise; fdescribe: (description: string, specDefinitions: Function) => Suite; spyOn: ( - obj: Record, + obj: Record, methodName: string, accessType?: keyof PropertyDescriptor, ) => Spy; diff --git a/packages/jest-jasmine2/src/jasmine/spyRegistry.ts b/packages/jest-jasmine2/src/jasmine/spyRegistry.ts index ffc70076b8c8..ae06e396650f 100644 --- a/packages/jest-jasmine2/src/jasmine/spyRegistry.ts +++ b/packages/jest-jasmine2/src/jasmine/spyRegistry.ts @@ -39,7 +39,10 @@ const formatErrorMsg = (domain: string, usage?: string) => { return (msg: string) => domain + ' : ' + msg + usageDefinition; }; -function isSpy(putativeSpy: any) { +function isSpy(putativeSpy: { + and: unknown; + calls: unknown; +}): putativeSpy is Spy { if (!putativeSpy) { return false; } @@ -54,7 +57,7 @@ const getErrorMsg = formatErrorMsg('', 'spyOn(, )'); export default class SpyRegistry { allowRespy: (allow: unknown) => void; spyOn: ( - obj: Record, + obj: Record, methodName: string, accessType?: keyof PropertyDescriptor, ) => Spy; @@ -62,7 +65,7 @@ export default class SpyRegistry { respy: unknown; private _spyOnProperty: ( - obj: Record, + obj: Record, propertyName: string, accessType: keyof PropertyDescriptor, ) => Spy; diff --git a/packages/jest-message-util/src/index.ts b/packages/jest-message-util/src/index.ts index e515dcea6ab3..b82b512690fa 100644 --- a/packages/jest-message-util/src/index.ts +++ b/packages/jest-message-util/src/index.ts @@ -321,12 +321,15 @@ export const formatResultsErrors = ( options: StackTraceOptions, testPath?: Path, ): string | null => { - const failedResults: FailedResults = testResults.reduce((errors, result) => { - result.failureMessages - .map(checkForCommonEnvironmentErrors) - .forEach(content => errors.push({content, result})); - return errors; - }, [] as FailedResults); + const failedResults: FailedResults = testResults.reduce( + (errors, result) => { + result.failureMessages + .map(checkForCommonEnvironmentErrors) + .forEach(content => errors.push({content, result})); + return errors; + }, + [], + ); if (!failedResults.length) { return null; diff --git a/packages/jest-resolve/src/nodeModulesPaths.ts b/packages/jest-resolve/src/nodeModulesPaths.ts index f1f303f57471..dddf52229a13 100644 --- a/packages/jest-resolve/src/nodeModulesPaths.ts +++ b/packages/jest-resolve/src/nodeModulesPaths.ts @@ -54,7 +54,7 @@ export default function nodeModulesPaths( } const dirs = paths - .reduce( + .reduce>( (dirs, aPath) => dirs.concat( modules.map(moduleDir => @@ -65,7 +65,7 @@ export default function nodeModulesPaths( : path.join(prefix, aPath, moduleDir), ), ), - [] as Array, + [], ) .filter(dir => dir !== ''); diff --git a/packages/jest-validate/src/validateCLIOptions.ts b/packages/jest-validate/src/validateCLIOptions.ts index 13fa57af6421..d24c5debf80d 100644 --- a/packages/jest-validate/src/validateCLIOptions.ts +++ b/packages/jest-validate/src/validateCLIOptions.ts @@ -87,19 +87,18 @@ export default function validateCLIOptions( throw createCLIValidationError(unrecognizedOptions, allowedOptions); } - const CLIDeprecations = Object.keys(deprecationEntries).reduce( - (acc, entry) => { - if (options[entry]) { - acc[entry] = deprecationEntries[entry]; - const alias = options[entry].alias as string; - if (alias) { - acc[alias] = deprecationEntries[entry]; - } + const CLIDeprecations = Object.keys(deprecationEntries).reduce< + Record + >((acc, entry) => { + if (options[entry]) { + acc[entry] = deprecationEntries[entry]; + const alias = options[entry].alias as string; + if (alias) { + acc[alias] = deprecationEntries[entry]; } - return acc; - }, - {} as Record, - ); + } + return acc; + }, {}); const deprecations = new Set(Object.keys(CLIDeprecations)); const deprecatedOptions = Object.keys(argv).filter( arg => deprecations.has(arg) && argv[arg] != null, diff --git a/packages/pretty-format/src/collections.ts b/packages/pretty-format/src/collections.ts index b56fbbd762d1..e97c3ceb6a13 100644 --- a/packages/pretty-format/src/collections.ts +++ b/packages/pretty-format/src/collections.ts @@ -28,7 +28,7 @@ const getKeysOfEnumerableProperties = (object: Record) => { * without surrounding punctuation (for example, braces) */ export function printIteratorEntries( - iterator: Iterator, + iterator: Iterator<[unknown, unknown]>, config: Config, indentation: string, depth: number, @@ -86,7 +86,7 @@ export function printIteratorEntries( * without surrounding punctuation (braces or brackets) */ export function printIteratorValues( - iterator: Iterator, + iterator: Iterator, config: Config, indentation: string, depth: number, @@ -165,7 +165,7 @@ export function printListItems( * without surrounding punctuation (for example, braces) */ export function printObjectProperties( - val: Record, + val: Record, config: Config, indentation: string, depth: number, diff --git a/packages/pretty-format/src/plugins/ConvertAnsi.ts b/packages/pretty-format/src/plugins/ConvertAnsi.ts index f4f95e841a67..a500dad114eb 100644 --- a/packages/pretty-format/src/plugins/ConvertAnsi.ts +++ b/packages/pretty-format/src/plugins/ConvertAnsi.ts @@ -56,7 +56,7 @@ const toHumanReadableAnsi = (text: string) => } }); -export const test: NewPlugin['test'] = (val: any) => +export const test: NewPlugin['test'] = (val: unknown) => typeof val === 'string' && !!val.match(ansiRegex()); export const serialize: NewPlugin['serialize'] = ( diff --git a/packages/pretty-format/src/plugins/DOMCollection.ts b/packages/pretty-format/src/plugins/DOMCollection.ts index 7d0b977be1cd..f58ee48023ee 100644 --- a/packages/pretty-format/src/plugins/DOMCollection.ts +++ b/packages/pretty-format/src/plugins/DOMCollection.ts @@ -17,20 +17,17 @@ const ARRAY_REGEXP = /^(HTML\w*Collection|NodeList)$/; const testName = (name: any) => OBJECT_NAMES.indexOf(name) !== -1 || ARRAY_REGEXP.test(name); -export const test: NewPlugin['test'] = (val: any) => +export const test: NewPlugin['test'] = (val: object) => val && val.constructor && - val.constructor.name && + !!val.constructor.name && testName(val.constructor.name); -// Convert array of attribute objects to props object. -const propsReducer = (props: any, attribute: any) => { - props[attribute.name] = attribute.value; - return props; -}; +const isNamedNodeMap = (collection: object): collection is NamedNodeMap => + collection.constructor.name === 'NamedNodeMap'; export const serialize: NewPlugin['serialize'] = ( - collection: any, + collection: any | NamedNodeMap, config: Config, indentation: string, depth: number, @@ -47,8 +44,14 @@ export const serialize: NewPlugin['serialize'] = ( (OBJECT_NAMES.indexOf(name) !== -1 ? '{' + printObjectProperties( - name === 'NamedNodeMap' - ? Array.prototype.reduce.call(collection, propsReducer, {}) + isNamedNodeMap(collection) + ? Array.from(collection).reduce>( + (props, attribute) => { + props[attribute.name] = attribute.value; + return props; + }, + {}, + ) : {...collection}, config, indentation, diff --git a/packages/pretty-format/src/plugins/DOMElement.ts b/packages/pretty-format/src/plugins/DOMElement.ts index ac8dffd68203..daf8f9be721f 100644 --- a/packages/pretty-format/src/plugins/DOMElement.ts +++ b/packages/pretty-format/src/plugins/DOMElement.ts @@ -23,7 +23,7 @@ const FRAGMENT_NODE = 11; const ELEMENT_REGEXP = /^((HTML|SVG)\w*)?Element$/; -const testNode = (nodeType: any, name: any) => +const testNode = (nodeType: number, name: string) => (nodeType === ELEMENT_NODE && ELEMENT_REGEXP.test(name)) || (nodeType === TEXT_NODE && name === 'Text') || (nodeType === COMMENT_NODE && name === 'Comment') || @@ -82,11 +82,14 @@ export const serialize: NewPlugin['serialize'] = ( .map(attr => attr.name) .sort(), nodeIsFragment(node) - ? [] - : Array.from(node.attributes).reduce((props, attribute) => { - props[attribute.name] = attribute.value; - return props; - }, {} as any), + ? {} + : Array.from(node.attributes).reduce>( + (props, attribute) => { + props[attribute.name] = attribute.value; + return props; + }, + {}, + ), config, indentation + config.indent, depth, diff --git a/packages/pretty-format/src/plugins/ReactElement.ts b/packages/pretty-format/src/plugins/ReactElement.ts index 56b777142ee9..a8091845ff99 100644 --- a/packages/pretty-format/src/plugins/ReactElement.ts +++ b/packages/pretty-format/src/plugins/ReactElement.ts @@ -17,7 +17,7 @@ import { // Given element.props.children, or subtree during recursive traversal, // return flattened array of children. -const getChildren = (arg: Array, children = []) => { +const getChildren = (arg: Array, children = []) => { if (Array.isArray(arg)) { arg.forEach(item => { getChildren(item, children); @@ -115,7 +115,7 @@ export const serialize: NewPlugin['serialize'] = ( indentation, ); -export const test: NewPlugin['test'] = (val: any) => +export const test: NewPlugin['test'] = (val: unknown) => val && ReactIs.isElement(val); const plugin: NewPlugin = {serialize, test}; diff --git a/packages/pretty-format/src/plugins/ReactTestComponent.ts b/packages/pretty-format/src/plugins/ReactTestComponent.ts index 66cbe78895f2..b58d31d36ec3 100644 --- a/packages/pretty-format/src/plugins/ReactTestComponent.ts +++ b/packages/pretty-format/src/plugins/ReactTestComponent.ts @@ -10,7 +10,7 @@ import type {Config, NewPlugin, Printer, Refs} from '../types'; export type ReactTestObject = { $$typeof: symbol; type: string; - props?: Record; + props?: Record; children?: null | Array; }; diff --git a/packages/pretty-format/src/types.ts b/packages/pretty-format/src/types.ts index ccc191231a0b..a2657b9e6c63 100644 --- a/packages/pretty-format/src/types.ts +++ b/packages/pretty-format/src/types.ts @@ -13,8 +13,8 @@ export type Colors = { value: {close: string; open: string}; }; type Indent = (arg0: string) => string; -export type Refs = Array; -type Print = (arg0: any) => string; +export type Refs = Array; +type Print = (arg0: unknown) => string; export type Theme = { comment: string; @@ -73,7 +73,7 @@ export type Config = { }; export type Printer = ( - val: any, + val: unknown, config: Config, indentation: string, depth: number, @@ -103,7 +103,7 @@ type PluginOptions = { export type OldPlugin = { print: ( - val: any, + val: unknown, print: Print, indent: Indent, options: PluginOptions,