eslint-cdk-plugin 3.4.3 → 3.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/index.cjs +29329 -1420
  2. package/dist/index.d.cts +72 -0
  3. package/dist/index.d.cts.map +1 -0
  4. package/dist/index.d.mts +72 -0
  5. package/dist/index.d.mts.map +1 -0
  6. package/dist/index.mjs +29329 -1396
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +21 -21
  9. package/src/configs/flat-config.ts +69 -0
  10. package/src/configs/index.ts +6 -0
  11. package/src/core/ast-node/finder/child-nodes.ts +25 -0
  12. package/src/{utils/getConstructor.ts → core/ast-node/finder/constructor.ts} +1 -1
  13. package/src/core/ast-node/finder/property-name.ts +20 -0
  14. package/src/core/ast-node/finder/public-property.ts +76 -0
  15. package/src/core/cdk-construct/type-checker/is-construct-or-stack.ts +21 -0
  16. package/src/core/cdk-construct/type-checker/is-construct.ts +22 -0
  17. package/src/{utils → core/cdk-construct/type-checker}/is-resource-with-readonly-interface.ts +8 -7
  18. package/src/core/cdk-construct/type-checker/is-resource.ts +17 -0
  19. package/src/core/cdk-construct/type-finder/index.ts +73 -0
  20. package/src/core/ts-type/checker/is-array.ts +15 -0
  21. package/src/core/ts-type/checker/is-class.ts +7 -0
  22. package/src/core/ts-type/checker/is-extends-target-super-class.ts +24 -0
  23. package/src/core/ts-type/checker/private/get-symbol.ts +5 -0
  24. package/src/core/ts-type/finder/array-element.ts +20 -0
  25. package/src/core/ts-type/finder/constructor-property-name.ts +21 -0
  26. package/src/{utils/getGenericTypeArgument.ts → core/ts-type/finder/generics-type-argument.ts} +5 -5
  27. package/src/index.ts +6 -108
  28. package/src/rules/construct-constructor-property.ts +48 -26
  29. package/src/rules/index.ts +34 -0
  30. package/src/rules/no-construct-in-interface.ts +5 -51
  31. package/src/rules/no-construct-in-public-property-of-construct.ts +20 -143
  32. package/src/rules/no-construct-stack-suffix.ts +5 -5
  33. package/src/rules/no-mutable-property-of-props-interface.ts +1 -1
  34. package/src/rules/no-mutable-public-property-of-construct.ts +47 -39
  35. package/src/rules/no-parent-name-construct-id-match.ts +4 -6
  36. package/src/rules/no-unused-props/index.ts +161 -0
  37. package/src/rules/no-unused-props/props-usage-analyzer.ts +314 -0
  38. package/src/{utils/propsUsageTracker.ts → rules/no-unused-props/props-usage-tracker.ts} +99 -106
  39. package/src/rules/no-unused-props/visitor/direct-props-usage-visitor.ts +145 -0
  40. package/src/rules/no-unused-props/visitor/index.ts +5 -0
  41. package/src/rules/no-unused-props/visitor/instance-variable-usage-visitor.ts +117 -0
  42. package/src/rules/no-unused-props/visitor/interface/node-visitor.ts +9 -0
  43. package/src/rules/no-unused-props/visitor/method-call-collector-visitor.ts +60 -0
  44. package/src/rules/no-unused-props/visitor/props-alias-visitor.ts +81 -0
  45. package/src/rules/no-unused-props/visitor/traverse-nodes.ts +38 -0
  46. package/src/rules/no-variable-construct-id.ts +4 -4
  47. package/src/rules/pascal-case-construct-id.ts +5 -5
  48. package/src/rules/props-name-convention.ts +4 -4
  49. package/src/rules/require-jsdoc.ts +2 -2
  50. package/src/rules/require-passing-this.ts +4 -4
  51. package/src/rules/require-props-default-doc.ts +1 -1
  52. package/bin/migration.mjs +0 -100
  53. package/dist/index.d.ts +0 -47
  54. package/dist/index.d.ts.map +0 -1
  55. package/src/constants/tsInternalFlags.ts +0 -18
  56. package/src/rules/no-unused-props.ts +0 -176
  57. package/src/utils/getArrayElementType.ts +0 -14
  58. package/src/utils/getPropertyNames.ts +0 -45
  59. package/src/utils/typecheck/cdk.ts +0 -71
  60. package/src/utils/typecheck/ts-node.ts +0 -42
  61. package/src/utils/typecheck/ts-type.ts +0 -27
  62. /package/src/{utils/convertString.ts → shared/converter/to-pascal-case.ts} +0 -0
  63. /package/src/{utils/createRule.ts → shared/create-rule.ts} +0 -0
package/dist/index.d.ts DELETED
@@ -1,47 +0,0 @@
1
- import { FlatConfig } from "@typescript-eslint/utils/ts-eslint";
2
- declare const rules: {
3
- "construct-constructor-property": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructorProperty" | "invalidConstructorType" | "invalidConstructorIdType", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
4
- "no-construct-in-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidInterfaceProperty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
5
- "no-construct-in-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
6
- "no-construct-stack-suffix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [{
7
- disallowedSuffixes?: ("Construct" | "Stack")[];
8
- }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
9
- "no-import-private": import("eslint").Rule.RuleModule;
10
- "no-mutable-property-of-props-interface": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropertyOfPropsInterface", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
11
- "no-mutable-public-property-of-construct": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPublicPropertyOfConstruct", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
12
- "no-parent-name-construct-id-match": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", {
13
- disallowContainingParentName?: boolean;
14
- }[], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
15
- "no-unused-props": import("@typescript-eslint/utils/ts-eslint").RuleModule<"unusedProp", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
16
- "no-variable-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
17
- "pascal-case-construct-id": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidConstructId", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
18
- "props-name-convention": import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPropsName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
19
- "require-jsdoc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingJSDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
20
- "require-passing-this": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingPassingThis", {
21
- allowNonThisAndDisallowScope?: boolean;
22
- }[], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
23
- "require-props-default-doc": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingDefaultDoc", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
24
- };
25
- declare const configs: {
26
- recommended: {
27
- languageOptions: FlatConfig.LanguageOptions;
28
- plugins: FlatConfig.Plugins;
29
- rules: FlatConfig.Rules;
30
- };
31
- strict: {
32
- languageOptions: FlatConfig.LanguageOptions;
33
- plugins: FlatConfig.Plugins;
34
- rules: FlatConfig.Rules;
35
- };
36
- };
37
- export { configs, rules };
38
- export interface EslintCdkPlugin {
39
- rules: typeof rules;
40
- configs: Readonly<{
41
- recommended: FlatConfig.Config;
42
- strict: FlatConfig.Config;
43
- }>;
44
- }
45
- declare const eslintCdkPlugin: EslintCdkPlugin;
46
- export default eslintCdkPlugin;
47
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAoBhE,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;CAiBV,CAAC;AAmEF,QAAA,MAAM,OAAO;;yBAzDM,UAAU,CAAC,eAAe;iBAClC,UAAU,CAAC,OAAO;eACpB,UAAU,CAAC,KAAK;;;yBAFN,UAAU,CAAC,eAAe;iBAClC,UAAU,CAAC,OAAO;eACpB,UAAU,CAAC,KAAK;;CA0DxB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,OAAO,EAAE,QAAQ,CAAC;QAChB,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC;QAC/B,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;KAC3B,CAAC,CAAC;CACJ;AAED,QAAA,MAAM,eAAe,EAAE,eAGtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,18 +0,0 @@
1
- /**
2
- * Implementing `SymbolFlags` defined in typescript on your own, in order not to include TypeScript in dependencies
3
- */
4
- export const SYMBOL_FLAGS = {
5
- CLASS: 32,
6
- Interface: 64,
7
- } as const;
8
-
9
- /**
10
- * Implementing `SyntaxKind` defined in typescript on your own, in order not to include TypeScript in dependencies
11
- */
12
- export const SYNTAX_KIND = {
13
- CLASS_DECLARATION: 263,
14
- CONSTRUCTOR: 176,
15
- IMPLEMENTS_KEYWORD: 119,
16
- IDENTIFIER: 80,
17
- PROPERTY_ACCESS_EXPRESSION: 211,
18
- } as const;
@@ -1,176 +0,0 @@
1
- import {
2
- AST_NODE_TYPES,
3
- ESLintUtils,
4
- ParserServicesWithTypeInformation,
5
- TSESLint,
6
- TSESTree,
7
- } from "@typescript-eslint/utils";
8
-
9
- import { createRule } from "../utils/createRule";
10
- import { getConstructor } from "../utils/getConstructor";
11
- import {
12
- IPropsUsageTracker,
13
- propsUsageTrackerFactory,
14
- } from "../utils/propsUsageTracker";
15
- import { isConstructType } from "../utils/typecheck/cdk";
16
-
17
- type Context = TSESLint.RuleContext<"unusedProp", []>;
18
-
19
- /**
20
- * Enforces that all properties defined in props type are used within the constructor
21
- * @param context - The rule context provided by ESLint
22
- * @returns An object containing the AST visitor functions
23
- */
24
- export const noUnusedProps = createRule({
25
- name: "no-unused-props",
26
- meta: {
27
- type: "suggestion",
28
- docs: {
29
- description:
30
- "Enforces that all properties defined in props type are used within the constructor",
31
- },
32
- messages: {
33
- unusedProp: "Property '{{propName}}' is defined in props but never used",
34
- },
35
- schema: [],
36
- },
37
- defaultOptions: [],
38
- create(context) {
39
- const parserServices = ESLintUtils.getParserServices(context);
40
-
41
- return {
42
- ClassDeclaration(node) {
43
- const type = parserServices.getTypeAtLocation(node);
44
- if (!isConstructType(type)) return;
45
-
46
- const constructor = getConstructor(node);
47
- if (!constructor) return;
48
-
49
- analyzePropsUsage(constructor, context, parserServices);
50
- },
51
- };
52
- },
53
- });
54
-
55
- /**
56
- * Analyzes props usage in the constructor
57
- */
58
- const analyzePropsUsage = (
59
- constructor: TSESTree.MethodDefinition,
60
- context: Context,
61
- parserServices: ParserServicesWithTypeInformation
62
- ): void => {
63
- const params = constructor.value.params;
64
-
65
- // NOTE: Check if constructor has props parameter (3rd parameter)
66
- if (params.length < 3) return;
67
-
68
- const propsParam = params[2];
69
-
70
- switch (propsParam.type) {
71
- case AST_NODE_TYPES.Identifier: {
72
- // NOTE: Standard props parameter (e.g. props: MyConstructProps)
73
- const propsType = parserServices.getTypeAtLocation(propsParam);
74
- const tracker = propsUsageTrackerFactory(propsType);
75
- if (!tracker || !constructor.value.body) return;
76
-
77
- analyzeConstructorBody(constructor.value.body, propsParam.name, tracker);
78
- reportUnusedProperties(tracker, propsParam, context);
79
- return;
80
- }
81
- case AST_NODE_TYPES.ObjectPattern: {
82
- // NOTE: Inline destructuring (e.g. { bucketName, enableVersioning }: MyConstructProps)
83
- const typeAnnotation = propsParam.typeAnnotation?.typeAnnotation;
84
- if (!typeAnnotation) return;
85
-
86
- const propsType = parserServices.getTypeAtLocation(typeAnnotation);
87
- const tracker = propsUsageTrackerFactory(propsType);
88
- if (!tracker) return;
89
-
90
- tracker.markAsUsedForObjectPattern(propsParam);
91
- reportUnusedProperties(tracker, propsParam, context);
92
- return;
93
- }
94
- default:
95
- return;
96
- }
97
- };
98
-
99
- /**
100
- * Analyzes constructor body for props usage patterns
101
- */
102
- const analyzeConstructorBody = (
103
- body: TSESTree.BlockStatement,
104
- propsParamName: string,
105
- tracker: IPropsUsageTracker
106
- ): void => {
107
- const visited = new Set<TSESTree.Node>();
108
-
109
- const visitNode = (node: TSESTree.Node): void => {
110
- if (visited.has(node)) return;
111
- visited.add(node);
112
-
113
- switch (node.type) {
114
- case AST_NODE_TYPES.MemberExpression:
115
- tracker.markAsUsedForMemberExpression(node, propsParamName);
116
- break;
117
- case AST_NODE_TYPES.VariableDeclarator:
118
- tracker.markAsUsedForVariableDeclarator(node, propsParamName);
119
- break;
120
- case AST_NODE_TYPES.AssignmentExpression:
121
- tracker.markAsUsedForAssignmentExpression(node, propsParamName);
122
- break;
123
- }
124
-
125
- // NOTE: Recursively visit child nodes
126
- const children = getChildNodes(node);
127
- for (const child of children) {
128
- visitNode(child);
129
- }
130
- };
131
-
132
- visitNode(body);
133
- };
134
-
135
- /**
136
- * Reports unused properties to ESLint
137
- */
138
- const reportUnusedProperties = (
139
- tracker: IPropsUsageTracker,
140
- propsParam: TSESTree.Parameter,
141
- context: Context
142
- ): void => {
143
- for (const propName of tracker.getUnusedProperties()) {
144
- context.report({
145
- node: propsParam,
146
- messageId: "unusedProp",
147
- data: {
148
- propName,
149
- },
150
- });
151
- }
152
- };
153
-
154
- /**
155
- * Safely gets child nodes from a TSESTree.Node
156
- */
157
- const getChildNodes = (node: TSESTree.Node): TSESTree.Node[] => {
158
- return Object.entries(node).reduce<TSESTree.Node[]>((acc, [key, value]) => {
159
- if (["parent", "range", "loc"].includes(key)) return acc; // Keys to skip to avoid circular references and unnecessary properties
160
- if (isESTreeNode(value)) return [...acc, value];
161
- if (Array.isArray(value)) return [...acc, ...value.filter(isESTreeNode)];
162
- return acc;
163
- }, []);
164
- };
165
-
166
- /**
167
- * Type guard to check if a value is a TSESTree.Node
168
- */
169
- const isESTreeNode = (value: unknown): value is TSESTree.Node => {
170
- return (
171
- value !== null &&
172
- typeof value === "object" &&
173
- "type" in value &&
174
- typeof (value as { type: unknown }).type === "string"
175
- );
176
- };
@@ -1,14 +0,0 @@
1
- import { Type } from "typescript";
2
-
3
- import { isArrayType } from "./typecheck/ts-type";
4
-
5
- export const getArrayElementType = (type: Type): Type | undefined => {
6
- if (!isArrayType(type)) return undefined;
7
-
8
- // Get type arguments for Array<T>
9
- if ("typeArguments" in type && Array.isArray(type.typeArguments)) {
10
- return (type.typeArguments as Type[])[0];
11
- }
12
-
13
- return undefined;
14
- };
@@ -1,45 +0,0 @@
1
- import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
2
- import { Type } from "typescript";
3
-
4
- import {
5
- isClassDeclaration,
6
- isConstructorDeclaration,
7
- } from "./typecheck/ts-node";
8
-
9
- /**
10
- * Retrieves the property names from an array of properties.
11
- *
12
- * @param properties An array of properties to extract names from.
13
- * @returns An array of property names.
14
- */
15
- export const getPropertyNames = (
16
- properties: (TSESTree.Property | TSESTree.RestElement)[]
17
- ): string[] => {
18
- return properties.reduce<string[]>(
19
- (acc, prop) =>
20
- prop.type === AST_NODE_TYPES.Property &&
21
- prop.key.type === AST_NODE_TYPES.Identifier
22
- ? [...acc, prop.key.name]
23
- : acc,
24
- []
25
- );
26
- };
27
-
28
- /**
29
- * Parses type to get the property names of the class constructor.
30
- * @returns The property names of the class constructor.
31
- */
32
- export const getConstructorPropertyNames = (type: Type): string[] => {
33
- const declarations = type.symbol?.declarations;
34
- if (!declarations?.length) return [];
35
-
36
- const classDeclaration = declarations[0];
37
- if (!isClassDeclaration(classDeclaration)) return [];
38
-
39
- const constructor = classDeclaration.members.find((member) =>
40
- isConstructorDeclaration(member)
41
- );
42
- if (!constructor?.parameters.length) return [];
43
-
44
- return constructor.parameters.map((param) => param.name.getText());
45
- };
@@ -1,71 +0,0 @@
1
- import { Type } from "typescript";
2
-
3
- type SuperClassType = "Construct" | "Stack" | "Resource";
4
-
5
- /**
6
- * Check if the type extends Construct or Stack
7
- * @param type - The type to check
8
- * @param ignoredClasses - Classes that inherit from Construct Class or Stack Class but do not want to be treated as Construct Class or Stack Class
9
- * @returns True if the type extends Construct or Stack, otherwise false
10
- */
11
- export const isConstructOrStackType = (
12
- type: Type,
13
- ignoredClasses: readonly string[] = ["App", "Stage", "CfnOutput"] as const
14
- ): boolean => {
15
- if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
16
- return isTargetSuperClassType(
17
- type,
18
- ["Construct", "Stack"],
19
- isConstructOrStackType
20
- );
21
- };
22
-
23
- /**
24
- * Check if the type extends Construct
25
- * @param type - The type to check
26
- * @param ignoredClasses - Classes that inherit from Construct Class but do not want to be treated as Construct Class
27
- * @returns True if the type extends Construct, otherwise false
28
- */
29
- export const isConstructType = (
30
- type: Type,
31
- ignoredClasses: readonly string[] = [
32
- "App",
33
- "Stage",
34
- "CfnOutput",
35
- "Stack",
36
- ] as const
37
- ): boolean => {
38
- if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
39
- return isTargetSuperClassType(type, ["Construct"], isConstructType);
40
- };
41
-
42
- export const isResourceType = (
43
- type: Type,
44
- ignoredClasses: readonly string[] = [] // App, Stage, CfnOutput, Stack are not extended Resource, so no need to ignore them
45
- ): boolean => {
46
- if (ignoredClasses.includes(type.symbol?.name ?? "")) return false;
47
- return isTargetSuperClassType(type, ["Resource"], isResourceType);
48
- };
49
-
50
- /**
51
- * Check if the type extends target super class
52
- * @param type - The type to check
53
- * @param targetSuperClasses - The target super classes
54
- * @returns True if the type extends target super class, otherwise false
55
- */
56
- const isTargetSuperClassType = (
57
- type: Type,
58
- targetSuperClasses: SuperClassType[],
59
- typeCheckFunction: (type: Type) => boolean
60
- ): boolean => {
61
- if (!type.symbol) return false;
62
-
63
- // NOTE: Check if the current type ends in target super class
64
- if (targetSuperClasses.some((suffix) => type.symbol.name === suffix)) {
65
- return true;
66
- }
67
-
68
- // NOTE: Check the base type
69
- const baseTypes = type.getBaseTypes() ?? [];
70
- return baseTypes.some((baseType) => typeCheckFunction(baseType));
71
- };
@@ -1,42 +0,0 @@
1
- import {
2
- ClassDeclaration,
3
- ConstructorDeclaration,
4
- HeritageClause,
5
- Identifier,
6
- Node,
7
- PropertyAccessExpression,
8
- } from "typescript";
9
-
10
- import { SYNTAX_KIND } from "../../constants/tsInternalFlags";
11
-
12
- // NOTE: In order not to make it dependent on the typescript library, it defines its own unions.
13
- // Therefore, the type information structures do not match.
14
- /* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
15
-
16
- // NOTE: Implementing type check method defined in typescript on your own, in order not to include TypeScript in dependencies
17
-
18
- export const isClassDeclaration = (node: Node): node is ClassDeclaration => {
19
- return node.kind === SYNTAX_KIND.CLASS_DECLARATION;
20
- };
21
-
22
- export const isIdentifier = (node: Node): node is Identifier => {
23
- return node.kind === SYNTAX_KIND.IDENTIFIER;
24
- };
25
-
26
- export const isPropertyAccessExpression = (
27
- node: Node
28
- ): node is PropertyAccessExpression => {
29
- return node.kind === SYNTAX_KIND.PROPERTY_ACCESS_EXPRESSION;
30
- };
31
-
32
- export const checkHeritageClauseIsImplements = (
33
- node: HeritageClause
34
- ): boolean => {
35
- return node.token === SYNTAX_KIND.IMPLEMENTS_KEYWORD;
36
- };
37
-
38
- export const isConstructorDeclaration = (
39
- node: Node
40
- ): node is ConstructorDeclaration => {
41
- return node.kind === SYNTAX_KIND.CONSTRUCTOR;
42
- };
@@ -1,27 +0,0 @@
1
- import { Symbol, Type } from "typescript";
2
-
3
- import { SYMBOL_FLAGS } from "../../constants/tsInternalFlags";
4
-
5
- // NOTE: In order not to make it dependent on the typescript library, it defines its own unions.
6
- // Therefore, the type information structures do not match.
7
- /* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
8
-
9
- const getSymbol = (type: Type): Symbol | undefined => {
10
- return type.getSymbol?.() ?? type.symbol;
11
- };
12
-
13
- export const isClassType = (type: Type): boolean => {
14
- return getSymbol(type)?.flags === SYMBOL_FLAGS.CLASS;
15
- };
16
-
17
- export const isArrayType = (type: Type): boolean => {
18
- const symbol = getSymbol(type);
19
- if (symbol?.name === "Array") return true;
20
-
21
- if ("target" in type && type.target) {
22
- const targetSymbol = getSymbol(type.target as Type);
23
- return targetSymbol?.name === "Array";
24
- }
25
-
26
- return false;
27
- };