@@ -3,6 +3,26 @@ const { ESLintUtils, AST_NODE_TYPES } = require('@typescript-eslint/utils');
33const utils = require ( '@typescript-eslint/type-utils' ) ;
44const ts = require ( 'typescript' ) ;
55
6+ // Object.groupBy clone
7+ /**
8+ * Groups an array of objects by a specified key or function.
9+ * @template T
10+ * @template {string} K
11+ * @param {T[] } arr - The array to group.
12+ * @param {((item: T) => K) } key
13+ * @return {Record<K, T[] | undefined> }
14+ */
15+ const groupBy = ( arr , key ) => {
16+ return arr . reduce ( ( acc , item ) => {
17+ const groupKey = key ( item ) ;
18+ if ( ! acc [ groupKey ] ) {
19+ acc [ groupKey ] = [ ] ;
20+ }
21+ acc [ groupKey ] . push ( item ) ;
22+ return acc ;
23+ } , /** @type {Record<string, T[]> } */ ( Object . create ( null ) ) ) ;
24+ } ;
25+
626/**
727 * @template {unknown} T
828 * @param {Readonly<T[]> } arr
@@ -173,23 +193,25 @@ const toFlattenedTypeArray = (types) =>
173193 * @param {import('@typescript-eslint/utils').ParserServicesWithTypeInformation['program'] } program
174194 * @param {import('typescript').Type[] } source
175195 * @param {import('typescript').Type[] } target
176- * @returns {boolean }
196+ * @returns {{ compatible?: import('typescript').Type[]; incompatible?: import('typescript').Type[] } }
177197 */
178- const isTypesAssignableTo = ( program , source , target ) => {
198+ const groupTypesByCompatibility = ( program , source , target ) => {
179199 const checker = program . getTypeChecker ( ) ;
180- return source
181- . every ( sourceType =>
182- target
183- . some ( targetType => {
184- if (
185- utils . isErrorLike ( program , sourceType ) &&
186- utils . isErrorLike ( program , targetType )
187- ) {
188- return utils . typeIsOrHasBaseType ( sourceType , targetType ) ;
189- }
190- return checker . isTypeAssignableTo ( sourceType , targetType ) ;
191- } )
200+
201+ return groupBy ( source , sourceType => {
202+ const isCompatible = target . some ( targetType => {
203+ if (
204+ utils . isErrorLike ( program , sourceType ) &&
205+ utils . isErrorLike ( program , targetType )
206+ ) {
207+ return utils . typeIsOrHasBaseType ( sourceType , targetType ) ;
208+ }
209+ return checker . isTypeAssignableTo ( sourceType , targetType ) ;
210+ } ) ;
211+ return /** @type {'compatible'|'incompatible' } */ (
212+ isCompatible ? 'compatible' : 'incompatible'
192213 ) ;
214+ } )
193215}
194216
195217/**
@@ -399,7 +421,7 @@ module.exports = {
399421 getJSDocThrowsTags,
400422 getJSDocThrowsTagTypes,
401423 toFlattenedTypeArray,
402- isTypesAssignableTo ,
424+ groupTypesByCompatibility ,
403425 findClosestFunctionNode,
404426 findNodeToComment,
405427 findIdentifierDeclaration,
0 commit comments