From 33eb0a785536caab5a872b719f6ec9066dff4e9b Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Mon, 13 Jan 2025 23:35:08 +0900 Subject: [PATCH 1/5] fix(eslint-plugin): [dot-notation] handle noPropertyAccessFromIndexSignature true --- .../eslint-plugin/src/rules/dot-notation.ts | 21 +++++++++++++------ ...ig.noPropertyAccessFromIndexSignature.json | 6 ++++++ .../tests/rules/dot-notation.test.ts | 16 ++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 packages/eslint-plugin/tests/fixtures/tsconfig.noPropertyAccessFromIndexSignature.json diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index dc57cec949fc..a3767f6956c6 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -9,7 +9,12 @@ import type { InferOptionsTypeFromRule, } from '../util'; -import { createRule, getModifiers, getParserServices } from '../util'; +import { + createRule, + getModifiers, + getParserServices, + getTypeName, +} from '../util'; import { getESLintCoreRule } from '../util/getESLintCoreRule'; const baseRule = getESLintCoreRule('dot-notation'); @@ -82,7 +87,7 @@ export default createRule({ create(context, [options]) { const rules = baseRule.create(context); const services = getParserServices(context); - + const checker = services.program.getTypeChecker(); const allowPrivateClassPropertyAccess = options.allowPrivateClassPropertyAccess; const allowProtectedClassPropertyAccess = @@ -125,12 +130,16 @@ export default createRule({ ) { return; } + if (propertySymbol == null && allowIndexSignaturePropertyAccess) { const objectType = services.getTypeAtLocation(node.object); - const indexType = objectType - .getNonNullableType() - .getStringIndexType(); - if (indexType != null) { + const indexType = objectType.getNonNullableType(); + const indexInfos = checker.getIndexInfosOfType(indexType); + if ( + indexInfos.some( + info => getTypeName(checker, info.keyType) === 'string', + ) + ) { return; } } diff --git a/packages/eslint-plugin/tests/fixtures/tsconfig.noPropertyAccessFromIndexSignature.json b/packages/eslint-plugin/tests/fixtures/tsconfig.noPropertyAccessFromIndexSignature.json new file mode 100644 index 000000000000..c3b3b86747f6 --- /dev/null +++ b/packages/eslint-plugin/tests/fixtures/tsconfig.noPropertyAccessFromIndexSignature.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noPropertyAccessFromIndexSignature": true + } +} diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 9355a46750af..1827051c99dc 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -150,6 +150,22 @@ console.log(x?.['priv_prop']); `, options: [{ allowProtectedClassPropertyAccess: true }], }, + { + code: ` +type Foo = { + bar: boolean; + [key: \`key_\${string}\`]: number; +}; +declare const foo: Foo; +foo['key_baz']; + `, + languageOptions: { + parserOptions: { + project: './tsconfig.noPropertyAccessFromIndexSignature.json', + tsconfigRootDir: rootPath, + }, + }, + }, ], invalid: [ { From 39e76a9f5cd5cf6ffd56ce17ff8896422b4f7651 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Mon, 13 Jan 2025 23:44:12 +0900 Subject: [PATCH 2/5] add test cases --- .../eslint-plugin/src/rules/dot-notation.ts | 1 - .../tests/rules/dot-notation.test.ts | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index a3767f6956c6..e48ac724f8af 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -130,7 +130,6 @@ export default createRule({ ) { return; } - if (propertySymbol == null && allowIndexSignaturePropertyAccess) { const objectType = services.getTypeAtLocation(node.object); const indexType = objectType.getNonNullableType(); diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 1827051c99dc..302796b5cd25 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -162,6 +162,25 @@ foo['key_baz']; languageOptions: { parserOptions: { project: './tsconfig.noPropertyAccessFromIndexSignature.json', + projectService: false, + tsconfigRootDir: rootPath, + }, + }, + }, + { + code: ` +type Key = Lowercase; +type Foo = { + BAR: boolean; + [key: Lowercase]: number; +}; +declare const foo: Foo; +foo['bar']; + `, + languageOptions: { + parserOptions: { + project: './tsconfig.noPropertyAccessFromIndexSignature.json', + projectService: false, tsconfigRootDir: rootPath, }, }, From 116d4c7d3fb6f2466159294b8b0d5c3080dc75e0 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Tue, 14 Jan 2025 22:34:24 +0900 Subject: [PATCH 3/5] add test cases --- .../tests/rules/dot-notation.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 302796b5cd25..78e56567cd6f 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -419,5 +419,22 @@ const x = new X(); x.prop = 'hello'; `, }, + { + code: ` +type Foo = { + bar: boolean; + [key: \`key_\${string}\`]: number; +}; +foo['key_baz']; + `, + errors: [{ messageId: 'useDot' }], + output: ` +type Foo = { + bar: boolean; + [key: \`key_\${string}\`]: number; +}; +foo.key_baz; + `, + }, ], }); From 41025ca0b1e7cab9cd0b296ffe3149e80cb7e5e8 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Mon, 20 Jan 2025 20:49:18 +0900 Subject: [PATCH 4/5] apply reviews --- packages/eslint-plugin/src/rules/dot-notation.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index e48ac724f8af..69d53170c70e 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -9,12 +9,7 @@ import type { InferOptionsTypeFromRule, } from '../util'; -import { - createRule, - getModifiers, - getParserServices, - getTypeName, -} from '../util'; +import { createRule, getModifiers, getParserServices } from '../util'; import { getESLintCoreRule } from '../util/getESLintCoreRule'; const baseRule = getESLintCoreRule('dot-notation'); @@ -131,12 +126,13 @@ export default createRule({ return; } if (propertySymbol == null && allowIndexSignaturePropertyAccess) { - const objectType = services.getTypeAtLocation(node.object); - const indexType = objectType.getNonNullableType(); - const indexInfos = checker.getIndexInfosOfType(indexType); + const objectType = services + .getTypeAtLocation(node.object) + .getNonNullableType(); + const indexInfos = checker.getIndexInfosOfType(objectType); if ( indexInfos.some( - info => getTypeName(checker, info.keyType) === 'string', + info => info.keyType.flags & ts.TypeFlags.StringLike, ) ) { return; From 2894e85a75d489c8ac6bffda7c8a932f4eec4ac0 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Mon, 3 Feb 2025 09:21:07 +0900 Subject: [PATCH 5/5] Add testcases --- .../tests/rules/dot-notation.test.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 78e56567cd6f..0a14e1036383 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -185,6 +185,27 @@ foo['bar']; }, }, }, + { + code: ` +type ExtraKey = \`extra\${string}\`; + +type Foo = { + foo: string; + [extraKey: ExtraKey]: number; +}; + +function f(x: T) { + x['extraKey']; +} + `, + languageOptions: { + parserOptions: { + project: './tsconfig.noPropertyAccessFromIndexSignature.json', + projectService: false, + tsconfigRootDir: rootPath, + }, + }, + }, ], invalid: [ { @@ -436,5 +457,32 @@ type Foo = { foo.key_baz; `, }, + { + code: ` +type ExtraKey = \`extra\${string}\`; + +type Foo = { + foo: string; + [extraKey: ExtraKey]: number; +}; + +function f(x: T) { + x['extraKey']; +} + `, + errors: [{ messageId: 'useDot' }], + output: ` +type ExtraKey = \`extra\${string}\`; + +type Foo = { + foo: string; + [extraKey: ExtraKey]: number; +}; + +function f(x: T) { + x.extraKey; +} + `, + }, ], }); 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