From 7007667ac82704b25b01f942127d76bc241bf320 Mon Sep 17 00:00:00 2001 From: chkt Date: Wed, 22 Jan 2020 19:00:31 +0100 Subject: [PATCH 1/3] Add spacing options for 'variable', 'parameter', 'property' and 'returnType' --- .../docs/rules/type-annotation-spacing.md | 2 +- .../src/rules/type-annotation-spacing.ts | 152 ++++++++++++++---- .../rules/type-annotation-spacing.test.ts | 124 ++++++++++++++ 3 files changed, 244 insertions(+), 34 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/type-annotation-spacing.md b/packages/eslint-plugin/docs/rules/type-annotation-spacing.md index c3a889cf36fd..a7c43a704ada 100644 --- a/packages/eslint-plugin/docs/rules/type-annotation-spacing.md +++ b/packages/eslint-plugin/docs/rules/type-annotation-spacing.md @@ -41,7 +41,7 @@ This rule has an object option: - `"before": true`, (default for arrow) requires a space before the colon/arrow. - `"after": true`, (default) requires a space after the colon/arrow. - `"after": false`, disallows spaces after the colon/arrow. -- `"overrides"`, overrides the default options for type annotations with `colon` (e.g. `const foo: string`) and function types with `arrow` (e.g. `type Foo = () => {}`). +- `"overrides"`, overrides the default options for type annotations with `colon` (e.g. `const foo: string`) and function types with `arrow` (e.g. `type Foo = () => {}`). Additionally allows granular overrides for `variable` (`const foo: string`),`parameter` (`function foo(bar: string) {...}`),`property` (`interface Foo { bar: string }`) and `returnType` (`function foo(): string {...}`) annotations. ### defaults diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 48ec12cfff81..3073e2a43520 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -1,22 +1,35 @@ -import { TSESTree } from '@typescript-eslint/experimental-utils'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/experimental-utils'; +import { Node } from "@typescript-eslint/typescript-estree/dist/ts-estree/ts-estree"; import * as util from '../util'; -type Options = [ - { - before?: boolean; - after?: boolean; - overrides?: { - colon?: { - before?: boolean; - after?: boolean; - }; - arrow?: { - before?: boolean; - after?: boolean; - }; - }; - }?, -]; +interface WhitespaceRule { + readonly before?: boolean; + readonly after?: boolean; +} + +interface WhitespaceOverride { + readonly colon?: WhitespaceRule; + readonly arrow?: WhitespaceRule; + readonly variable? : WhitespaceRule; + readonly property?: WhitespaceRule; + readonly parameter?: WhitespaceRule; + readonly returnType?: WhitespaceRule; +} + +interface Config extends WhitespaceRule { + readonly overrides?: WhitespaceOverride; +} + +interface WhitespaceRules { + colon: WhitespaceRule; + arrow: WhitespaceRule; + variable: WhitespaceRule; + parameter: WhitespaceRule; + property: WhitespaceRule; + returnType: WhitespaceRule; +} + +type Options = [ Config? ]; type MessageIds = | 'expectedSpaceAfter' | 'expectedSpaceBefore' @@ -32,6 +45,89 @@ const definition = { additionalProperties: false, }; + +function createSettings(options?: Config): WhitespaceRules { + const globals = { + ...(options?.before !== undefined ? { before : options.before } : {}), + ...(options?.after !== undefined ? { after : options.after } : {}) + }; + const override = options?.overrides ?? {}; + const colon = { ...{ before : false, after : true }, ...globals, ...override?.colon }; + const arrow = { ...{ before : true, after : true }, ...globals, ...override?.arrow }; + + return { + colon: colon, + arrow: arrow, + variable: { ...colon, ...override?.variable }, + property: { ...colon, ...override?.property }, + parameter: { ...colon, ...override?.parameter }, + returnType: { ...colon, ...override?.returnType } + }; +} + + +function getNodeType(node?: Node): string { + return node?.type ?? ''; +} + +function typeIsArrowFunction(type: string): boolean { + return type === AST_NODE_TYPES.TSFunctionType; +} + +function typeIsIdentifier(type: string): boolean { + return type === AST_NODE_TYPES.Identifier; +} + +function typeIsProperty(type: string): boolean { + return [ + AST_NODE_TYPES.ClassProperty, + AST_NODE_TYPES.FunctionExpression, + AST_NODE_TYPES.TSPropertySignature, + AST_NODE_TYPES.TSMethodSignature + ].includes(type as AST_NODE_TYPES); +} + +function typeIsReturnType(type: string): boolean { + return [ + AST_NODE_TYPES.FunctionDeclaration, + AST_NODE_TYPES.ArrowFunctionExpression + ].includes(type as AST_NODE_TYPES); +} + +function typeIsVariable(type: string): boolean { + return type === AST_NODE_TYPES.VariableDeclarator; +} + +function typeIsParameter(type: string): boolean { + return [ + AST_NODE_TYPES.FunctionDeclaration, + AST_NODE_TYPES.TSFunctionType, + AST_NODE_TYPES.TSMethodSignature, + AST_NODE_TYPES.TSEmptyBodyFunctionExpression + ].includes(type as AST_NODE_TYPES); +} + +function getIdentifierSettings(rules: WhitespaceRules, node?: Node): WhitespaceRule { + const scope = node?.parent; + const type = getNodeType(scope); + + if (typeIsVariable(type)) return rules.variable; + else if (typeIsParameter(type)) return rules.parameter; + else return rules.colon; +} + +function getSettings(rules: WhitespaceRules, node: Node): WhitespaceRule { + const scope = node?.parent?.parent; + const type = getNodeType(scope); + + if (typeIsArrowFunction(type)) return rules.arrow; + else if (typeIsIdentifier(type)) return getIdentifierSettings(rules, scope); + else if (typeIsProperty(type)) return rules.property; + else if (typeIsReturnType(type)) return rules.returnType; + else return rules.colon; +} + + export default util.createRule({ name: 'type-annotation-spacing', meta: { @@ -59,6 +155,10 @@ export default util.createRule({ properties: { colon: definition, arrow: definition, + variable: definition, + parameter: definition, + property: definition, + returnType: definition }, additionalProperties: false, }, @@ -76,20 +176,7 @@ export default util.createRule({ const punctuators = [':', '=>']; const sourceCode = context.getSourceCode(); - const overrides = options?.overrides ?? { colon: {}, arrow: {} }; - - const colonOptions = Object.assign( - {}, - { before: false, after: true }, - options, - overrides.colon, - ); - const arrowOptions = Object.assign( - {}, - { before: true, after: true }, - options, - overrides.arrow, - ); + const settings = createSettings(options); /** * Checks if there's proper spacing around type annotations (no space @@ -108,8 +195,7 @@ export default util.createRule({ return; } - const before = type === ':' ? colonOptions.before : arrowOptions.before; - const after = type === ':' ? colonOptions.after : arrowOptions.after; + const { before, after } = getSettings(settings, typeAnnotation); if (type === ':' && previousToken.value === '?') { // shift the start to the ? diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 04abdc81a472..03219ee5efbe 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -1034,6 +1034,130 @@ type Bar = Record ], }, 'let resolver: (() => PromiseLike) | PromiseLike;', + { + code : 'const foo:string;', + options : [{ + overrides: { + colon: { + after: false, + before: true + }, + variable: { + before: false + } + } + }] + }, + { + code : 'const foo:string;', + options : [{ + before: true, + overrides: { + colon : { + after: true, + before: false + }, + variable: { + after: false + } + } + }] + }, + { + code: ` +interface Foo { + greet():string; +} + `, + options: [{ + overrides: { + colon: { + after: false, + before: true + }, + property: { + before: false + } + } + }] + }, + { + code: ` +interface Foo { + name:string; +} + `, + options: [{ + before: true, + overrides: { + colon: { + after:true, + before:false + }, + property: { + after: false + } + } + }] + }, + { + code: 'function foo(name:string) {}', + options: [{ + overrides: { + colon: { + after:false, + before:true + }, + parameter: { + before:false + } + } + }] + }, + { + code: 'function foo(name:string) {}', + options: [{ + before: true, + overrides: { + colon: { + after: true, + before: false + }, + parameter: { + after: false + } + } + }] + }, + { + code: 'function foo():string {}', + options: [{ + overrides: { + colon: { + after: false, + before: true + }, + returnType: { + before: false + } + } + }] + }, + { + code: 'function foo():string {}', + options: [{ + before: true, + overrides: { + colon: { + after: true, + before: false + }, + returnType: { + after: false + } + } + }] + } ], invalid: [ { From 4c715460c071df195c2f697847b74221ff17cbb9 Mon Sep 17 00:00:00 2001 From: chkt Date: Wed, 22 Jan 2020 19:34:56 +0100 Subject: [PATCH 2/3] Change to conform to project standards --- .../src/rules/type-annotation-spacing.ts | 80 +++++--- .../rules/type-annotation-spacing.test.ts | 194 ++++++++++-------- 2 files changed, 155 insertions(+), 119 deletions(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 3073e2a43520..03952f8d241b 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -1,5 +1,7 @@ -import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/experimental-utils'; -import { Node } from "@typescript-eslint/typescript-estree/dist/ts-estree/ts-estree"; +import { + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; import * as util from '../util'; interface WhitespaceRule { @@ -10,7 +12,7 @@ interface WhitespaceRule { interface WhitespaceOverride { readonly colon?: WhitespaceRule; readonly arrow?: WhitespaceRule; - readonly variable? : WhitespaceRule; + readonly variable?: WhitespaceRule; readonly property?: WhitespaceRule; readonly parameter?: WhitespaceRule; readonly returnType?: WhitespaceRule; @@ -29,7 +31,7 @@ interface WhitespaceRules { returnType: WhitespaceRule; } -type Options = [ Config? ]; +type Options = [Config?]; type MessageIds = | 'expectedSpaceAfter' | 'expectedSpaceBefore' @@ -45,15 +47,22 @@ const definition = { additionalProperties: false, }; - -function createSettings(options?: Config): WhitespaceRules { +function createRules(options?: Config): WhitespaceRules { const globals = { - ...(options?.before !== undefined ? { before : options.before } : {}), - ...(options?.after !== undefined ? { after : options.after } : {}) + ...(options?.before !== undefined ? { before: options.before } : {}), + ...(options?.after !== undefined ? { after: options.after } : {}), }; const override = options?.overrides ?? {}; - const colon = { ...{ before : false, after : true }, ...globals, ...override?.colon }; - const arrow = { ...{ before : true, after : true }, ...globals, ...override?.arrow }; + const colon = { + ...{ before: false, after: true }, + ...globals, + ...override?.colon, + }; + const arrow = { + ...{ before: true, after: true }, + ...globals, + ...override?.arrow, + }; return { colon: colon, @@ -61,12 +70,11 @@ function createSettings(options?: Config): WhitespaceRules { variable: { ...colon, ...override?.variable }, property: { ...colon, ...override?.property }, parameter: { ...colon, ...override?.parameter }, - returnType: { ...colon, ...override?.returnType } + returnType: { ...colon, ...override?.returnType }, }; } - -function getNodeType(node?: Node): string { +function getNodeType(node?: TSESTree.Node): string { return node?.type ?? ''; } @@ -83,14 +91,14 @@ function typeIsProperty(type: string): boolean { AST_NODE_TYPES.ClassProperty, AST_NODE_TYPES.FunctionExpression, AST_NODE_TYPES.TSPropertySignature, - AST_NODE_TYPES.TSMethodSignature + AST_NODE_TYPES.TSMethodSignature, ].includes(type as AST_NODE_TYPES); } function typeIsReturnType(type: string): boolean { return [ AST_NODE_TYPES.FunctionDeclaration, - AST_NODE_TYPES.ArrowFunctionExpression + AST_NODE_TYPES.ArrowFunctionExpression, ].includes(type as AST_NODE_TYPES); } @@ -103,31 +111,43 @@ function typeIsParameter(type: string): boolean { AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.TSFunctionType, AST_NODE_TYPES.TSMethodSignature, - AST_NODE_TYPES.TSEmptyBodyFunctionExpression + AST_NODE_TYPES.TSEmptyBodyFunctionExpression, ].includes(type as AST_NODE_TYPES); } -function getIdentifierSettings(rules: WhitespaceRules, node?: Node): WhitespaceRule { +function getIdentifierRules( + rules: WhitespaceRules, + node?: TSESTree.Node, +): WhitespaceRule { const scope = node?.parent; const type = getNodeType(scope); - if (typeIsVariable(type)) return rules.variable; - else if (typeIsParameter(type)) return rules.parameter; - else return rules.colon; + if (typeIsVariable(type)) { + return rules.variable; + } else if (typeIsParameter(type)) { + return rules.parameter; + } else { + return rules.colon; + } } -function getSettings(rules: WhitespaceRules, node: Node): WhitespaceRule { +function getRules(rules: WhitespaceRules, node: TSESTree.Node): WhitespaceRule { const scope = node?.parent?.parent; const type = getNodeType(scope); - if (typeIsArrowFunction(type)) return rules.arrow; - else if (typeIsIdentifier(type)) return getIdentifierSettings(rules, scope); - else if (typeIsProperty(type)) return rules.property; - else if (typeIsReturnType(type)) return rules.returnType; - else return rules.colon; + if (typeIsArrowFunction(type)) { + return rules.arrow; + } else if (typeIsIdentifier(type)) { + return getIdentifierRules(rules, scope); + } else if (typeIsProperty(type)) { + return rules.property; + } else if (typeIsReturnType(type)) { + return rules.returnType; + } else { + return rules.colon; + } } - export default util.createRule({ name: 'type-annotation-spacing', meta: { @@ -158,7 +178,7 @@ export default util.createRule({ variable: definition, parameter: definition, property: definition, - returnType: definition + returnType: definition, }, additionalProperties: false, }, @@ -176,7 +196,7 @@ export default util.createRule({ const punctuators = [':', '=>']; const sourceCode = context.getSourceCode(); - const settings = createSettings(options); + const ruleSet = createRules(options); /** * Checks if there's proper spacing around type annotations (no space @@ -195,7 +215,7 @@ export default util.createRule({ return; } - const { before, after } = getSettings(settings, typeAnnotation); + const { before, after } = getRules(ruleSet, typeAnnotation); if (type === ':' && previousToken.value === '?') { // shift the start to the ? diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 03219ee5efbe..e496743afc3e 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -1035,33 +1035,37 @@ type Bar = Record }, 'let resolver: (() => PromiseLike) | PromiseLike;', { - code : 'const foo:string;', - options : [{ - overrides: { - colon: { - after: false, - before: true + code: 'const foo:string;', + options: [ + { + overrides: { + colon: { + after: false, + before: true, + }, + variable: { + before: false, + }, }, - variable: { - before: false - } - } - }] - }, - { - code : 'const foo:string;', - options : [{ - before: true, - overrides: { - colon : { - after: true, - before: false + }, + ], + }, + { + code: 'const foo:string;', + options: [ + { + before: true, + overrides: { + colon: { + after: true, + before: false, + }, + variable: { + after: false, + }, }, - variable: { - after: false - } - } - }] + }, + ], }, { code: ` @@ -1069,17 +1073,19 @@ interface Foo { greet():string; } `, - options: [{ - overrides: { - colon: { - after: false, - before: true + options: [ + { + overrides: { + colon: { + after: false, + before: true, + }, + property: { + before: false, + }, }, - property: { - before: false - } - } - }] + }, + ], }, { code: ` @@ -1087,77 +1093,87 @@ interface Foo { name:string; } `, - options: [{ - before: true, - overrides: { - colon: { - after:true, - before:false + options: [ + { + before: true, + overrides: { + colon: { + after: true, + before: false, + }, + property: { + after: false, + }, }, - property: { - after: false - } - } - }] + }, + ], }, { code: 'function foo(name:string) {}', - options: [{ - overrides: { - colon: { - after:false, - before:true + options: [ + { + overrides: { + colon: { + after: false, + before: true, + }, + parameter: { + before: false, + }, }, - parameter: { - before:false - } - } - }] + }, + ], }, { code: 'function foo(name:string) {}', - options: [{ - before: true, - overrides: { - colon: { - after: true, - before: false + options: [ + { + before: true, + overrides: { + colon: { + after: true, + before: false, + }, + parameter: { + after: false, + }, }, - parameter: { - after: false - } - } - }] + }, + ], }, { code: 'function foo():string {}', - options: [{ - overrides: { - colon: { - after: false, - before: true + options: [ + { + overrides: { + colon: { + after: false, + before: true, + }, + returnType: { + before: false, + }, }, - returnType: { - before: false - } - } - }] + }, + ], }, { code: 'function foo():string {}', - options: [{ - before: true, - overrides: { - colon: { - after: true, - before: false + options: [ + { + before: true, + overrides: { + colon: { + after: true, + before: false, + }, + returnType: { + after: false, + }, }, - returnType: { - after: false - } - } - }] - } + }, + ], + }, ], invalid: [ { From 7ff57ee7f002b88cc817693aad50e075ca27f85a Mon Sep 17 00:00:00 2001 From: chkt Date: Sat, 29 Feb 2020 19:52:20 +0100 Subject: [PATCH 3/3] Update to satisfy code review --- .../src/rules/type-annotation-spacing.ts | 84 ++++------------ packages/eslint-plugin/src/util/astUtils.ts | 95 +++++++++++++++++++ 2 files changed, 116 insertions(+), 63 deletions(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 03952f8d241b..5b9dbfbaa4ad 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -1,8 +1,13 @@ -import { - AST_NODE_TYPES, - TSESTree, -} from '@typescript-eslint/experimental-utils'; +import { TSESTree } from '@typescript-eslint/experimental-utils'; import * as util from '../util'; +import { + isClassOrTypeElement, + isFunction, + isFunctionOrFunctionType, + isIdentifier, + isTSFunctionType, + isVariableDeclarator, +} from '../util'; interface WhitespaceRule { readonly before?: boolean; @@ -22,14 +27,7 @@ interface Config extends WhitespaceRule { readonly overrides?: WhitespaceOverride; } -interface WhitespaceRules { - colon: WhitespaceRule; - arrow: WhitespaceRule; - variable: WhitespaceRule; - parameter: WhitespaceRule; - property: WhitespaceRule; - returnType: WhitespaceRule; -} +type WhitespaceRules = Required; type Options = [Config?]; type MessageIds = @@ -74,74 +72,34 @@ function createRules(options?: Config): WhitespaceRules { }; } -function getNodeType(node?: TSESTree.Node): string { - return node?.type ?? ''; -} - -function typeIsArrowFunction(type: string): boolean { - return type === AST_NODE_TYPES.TSFunctionType; -} - -function typeIsIdentifier(type: string): boolean { - return type === AST_NODE_TYPES.Identifier; -} - -function typeIsProperty(type: string): boolean { - return [ - AST_NODE_TYPES.ClassProperty, - AST_NODE_TYPES.FunctionExpression, - AST_NODE_TYPES.TSPropertySignature, - AST_NODE_TYPES.TSMethodSignature, - ].includes(type as AST_NODE_TYPES); -} - -function typeIsReturnType(type: string): boolean { - return [ - AST_NODE_TYPES.FunctionDeclaration, - AST_NODE_TYPES.ArrowFunctionExpression, - ].includes(type as AST_NODE_TYPES); -} - -function typeIsVariable(type: string): boolean { - return type === AST_NODE_TYPES.VariableDeclarator; -} - -function typeIsParameter(type: string): boolean { - return [ - AST_NODE_TYPES.FunctionDeclaration, - AST_NODE_TYPES.TSFunctionType, - AST_NODE_TYPES.TSMethodSignature, - AST_NODE_TYPES.TSEmptyBodyFunctionExpression, - ].includes(type as AST_NODE_TYPES); -} - function getIdentifierRules( rules: WhitespaceRules, - node?: TSESTree.Node, + node: TSESTree.Node | undefined, ): WhitespaceRule { const scope = node?.parent; - const type = getNodeType(scope); - if (typeIsVariable(type)) { + if (isVariableDeclarator(scope)) { return rules.variable; - } else if (typeIsParameter(type)) { + } else if (isFunctionOrFunctionType(scope)) { return rules.parameter; } else { return rules.colon; } } -function getRules(rules: WhitespaceRules, node: TSESTree.Node): WhitespaceRule { +function getRules( + rules: WhitespaceRules, + node: TSESTree.TypeNode, +): WhitespaceRule { const scope = node?.parent?.parent; - const type = getNodeType(scope); - if (typeIsArrowFunction(type)) { + if (isTSFunctionType(scope)) { return rules.arrow; - } else if (typeIsIdentifier(type)) { + } else if (isIdentifier(scope)) { return getIdentifierRules(rules, scope); - } else if (typeIsProperty(type)) { + } else if (isClassOrTypeElement(scope)) { return rules.property; - } else if (typeIsReturnType(type)) { + } else if (isFunction(scope)) { return rules.returnType; } else { return rules.colon; diff --git a/packages/eslint-plugin/src/util/astUtils.ts b/packages/eslint-plugin/src/util/astUtils.ts index 29dcdc0b459f..a92f00eaa168 100644 --- a/packages/eslint-plugin/src/util/astUtils.ts +++ b/packages/eslint-plugin/src/util/astUtils.ts @@ -82,6 +82,95 @@ function isTypeAssertion( ); } +function isVariableDeclarator( + node: TSESTree.Node | undefined, +): node is TSESTree.VariableDeclarator { + return node?.type === AST_NODE_TYPES.VariableDeclarator; +} + +function isFunction( + node: TSESTree.Node | undefined, +): node is + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression { + if (!node) { + return false; + } + + return [ + AST_NODE_TYPES.ArrowFunctionExpression, + AST_NODE_TYPES.FunctionDeclaration, + AST_NODE_TYPES.FunctionExpression, + ].includes(node.type); +} + +function isFunctionType( + node: TSESTree.Node | undefined, +): node is + | TSESTree.TSCallSignatureDeclaration + | TSESTree.TSConstructSignatureDeclaration + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSFunctionType + | TSESTree.TSMethodSignature { + if (!node) { + return false; + } + + return [ + AST_NODE_TYPES.TSCallSignatureDeclaration, + AST_NODE_TYPES.TSConstructSignatureDeclaration, + AST_NODE_TYPES.TSEmptyBodyFunctionExpression, + AST_NODE_TYPES.TSFunctionType, + AST_NODE_TYPES.TSMethodSignature, + ].includes(node.type); +} + +function isFunctionOrFunctionType( + node: TSESTree.Node | undefined, +): node is + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + | TSESTree.TSCallSignatureDeclaration + | TSESTree.TSConstructSignatureDeclaration + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSFunctionType + | TSESTree.TSMethodSignature { + return isFunction(node) || isFunctionType(node); +} + +function isTSFunctionType( + node: TSESTree.Node | undefined, +): node is TSESTree.TSFunctionType { + return node?.type === AST_NODE_TYPES.TSFunctionType; +} + +function isClassOrTypeElement( + node: TSESTree.Node | undefined, +): node is TSESTree.ClassElement | TSESTree.TypeElement { + if (!node) { + return false; + } + + return [ + // ClassElement + AST_NODE_TYPES.ClassProperty, + AST_NODE_TYPES.FunctionExpression, + AST_NODE_TYPES.MethodDefinition, + AST_NODE_TYPES.TSAbstractClassProperty, + AST_NODE_TYPES.TSAbstractMethodDefinition, + AST_NODE_TYPES.TSEmptyBodyFunctionExpression, + AST_NODE_TYPES.TSIndexSignature, + // TypeElement + AST_NODE_TYPES.TSCallSignatureDeclaration, + AST_NODE_TYPES.TSConstructSignatureDeclaration, + // AST_NODE_TYPES.TSIndexSignature, + AST_NODE_TYPES.TSMethodSignature, + AST_NODE_TYPES.TSPropertySignature, + ].includes(node.type); +} + /** * Checks if a node is a constructor method. */ @@ -136,6 +225,10 @@ export { isAwaitExpression, isAwaitKeyword, isConstructor, + isClassOrTypeElement, + isFunction, + isFunctionOrFunctionType, + isFunctionType, isIdentifier, isLogicalOrOperator, isNonNullAssertionPunctuator, @@ -145,6 +238,8 @@ export { isOptionalOptionalChain, isSetter, isTokenOnSameLine, + isTSFunctionType, isTypeAssertion, + isVariableDeclarator, LINEBREAK_MATCHER, }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy