From 0b29c9311d85d76d5dd21c2356e64a94b3892608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Sat, 4 Sep 2021 11:23:28 +0200 Subject: [PATCH] feat(experimental-utils): extract `isNodeOfTypeWithConditions` out of `ast-utils`' `predicates` --- .../src/ast-utils/predicates.ts | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/packages/experimental-utils/src/ast-utils/predicates.ts b/packages/experimental-utils/src/ast-utils/predicates.ts index 7a7bcf520b1a..c42e82dfbb35 100644 --- a/packages/experimental-utils/src/ast-utils/predicates.ts +++ b/packages/experimental-utils/src/ast-utils/predicates.ts @@ -7,6 +7,26 @@ const isNodeOfType = ): node is TSESTree.Node & { type: NodeType } => node?.type === nodeType; +type ObjectEntry = [keyof BaseType, BaseType[keyof BaseType]]; +type ObjectEntries = Array>; +const isNodeOfTypeWithConditions = + < + NodeType extends AST_NODE_TYPES, + Conditions extends Partial, + >( + nodeType: NodeType, + conditions: Conditions, + ) => + ( + node: TSESTree.Node | null | undefined, + ): node is TSESTree.Node & { type: NodeType } & Conditions => + node?.type === nodeType && + ( + Object.entries(conditions) as ObjectEntries< + TSESTree.Node & { type: NodeType } + > + ).every(([key, value]) => node[key] === value); + function isOptionalChainPunctuator( token: TSESTree.Token, ): token is TSESTree.PunctuatorToken & { value: '?.' } { @@ -35,27 +55,20 @@ function isNotNonNullAssertionPunctuator( /** * Returns true if and only if the node represents: foo?.() or foo.bar?.() */ -function isOptionalCallExpression( - node: TSESTree.Node, -): node is TSESTree.CallExpression & { optional: true } { - return ( - node.type === AST_NODE_TYPES.CallExpression && - // this flag means the call expression itself is option - // i.e. it is foo.bar?.() and not foo?.bar() - node.optional - ); -} +const isOptionalCallExpression = isNodeOfTypeWithConditions( + AST_NODE_TYPES.CallExpression, + // this flag means the call expression itself is option + // i.e. it is foo.bar?.() and not foo?.bar() + { optional: true }, +); /** * Returns true if and only if the node represents logical OR */ -function isLogicalOrOperator( - node: TSESTree.Node, -): node is TSESTree.LogicalExpression & { operator: '||' } { - return ( - node.type === AST_NODE_TYPES.LogicalExpression && node.operator === '||' - ); -} +const isLogicalOrOperator = isNodeOfTypeWithConditions( + AST_NODE_TYPES.LogicalExpression, + { operator: '||' }, +); /** * Checks if a node is a type assertion: @@ -165,14 +178,10 @@ function isClassOrTypeElement( /** * Checks if a node is a constructor method. */ -function isConstructor( - node: TSESTree.Node | undefined, -): node is TSESTree.MethodDefinition { - return ( - node?.type === AST_NODE_TYPES.MethodDefinition && - node.kind === 'constructor' - ); -} +const isConstructor = isNodeOfTypeWithConditions( + AST_NODE_TYPES.MethodDefinition, + { kind: 'constructor' }, +); /** * Checks if a node is a setter method.