diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index a26f1422460e..8ba1be086c19 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -2,11 +2,28 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { createRule, nullThrows, NullThrowsReasons } from '../util'; +import { + createRule, + isReferenceToGlobalFunction, + nullThrows, + NullThrowsReasons, +} from '../util'; export type MessageIds = 'preferConstructor' | 'preferTypeAnnotation'; export type Options = ['constructor' | 'type-annotation']; +const builtInArrays = new Set([ + 'Float32Array', + 'Float64Array', + 'Int16Array', + 'Int32Array', + 'Int8Array', + 'Uint16Array', + 'Uint32Array', + 'Uint8Array', + 'Uint8ClampedArray', +]); + export default createRule({ name: 'consistent-generic-constructors', meta: { @@ -63,6 +80,18 @@ export default createRule({ ); } } + + function isBuiltInArray(typeName: TSESTree.Identifier) { + return ( + builtInArrays.has(typeName.name) && + isReferenceToGlobalFunction( + typeName.name, + typeName, + context.sourceCode, + ) + ); + } + const [lhsName, rhs] = getLHSRHS(); const lhs = lhsName.typeAnnotation?.typeAnnotation; @@ -77,7 +106,8 @@ export default createRule({ lhs && (lhs.type !== AST_NODE_TYPES.TSTypeReference || lhs.typeName.type !== AST_NODE_TYPES.Identifier || - lhs.typeName.name !== rhs.callee.name) + lhs.typeName.name !== rhs.callee.name || + isBuiltInArray(lhs.typeName)) ) { return; } diff --git a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts index 1a573186b1ae..f9a49b470805 100644 --- a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts @@ -44,6 +44,38 @@ class A { `, ` const a = function (a: Foo = new Foo()) {}; + `, + ` +const a: Float32Array = new Float32Array(); +export {}; + `, + ` +const a: Float64Array = new Float64Array(); +export {}; + `, + ` +const a: Int16Array = new Int16Array(); +export {}; + `, + ` +const a: Int8Array = new Int8Array(); +export {}; + `, + ` +const a: Uint16Array = new Uint16Array(); +export {}; + `, + ` +const a: Uint32Array = new Uint32Array(); +export {}; + `, + ` +const a: Uint8Array = new Uint8Array(); +export {}; + `, + ` +const a: Uint8ClampedArray = new Uint8ClampedArray(); +export {}; `, { code: ` @@ -592,5 +624,22 @@ const a = function (a = new Foo()) {}; const a = function (a: Foo = new Foo()) {}; `, }, + { + code: ` +class Float32Array {} +const a: Float32Array = new Float32Array(); +export {}; + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +class Float32Array {} +const a = new Float32Array(); +export {}; + `, + }, ], });