Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix(eslint-plugin): [no-deprecated] should allow ignoring of deprecated value #10670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: main
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38e69ff
feat: create valueMatchesSomeSpecifier function
y-hsgw Jan 17, 2025
ae6e55a
fix: ignore deprecated value
y-hsgw Jan 17, 2025
36d8055
test: add test
y-hsgw Jan 17, 2025
d545ea1
test: add test
y-hsgw Jan 25, 2025
a4463a4
refactor: use AST node narrowing
y-hsgw Feb 27, 2025
95839f6
feat: support package
y-hsgw Feb 27, 2025
b80196b
test: add test
y-hsgw Feb 27, 2025
4f7a71e
Merge branch 'main' of https://github.com/y-hsgw/typescript-eslint in…
y-hsgw Feb 27, 2025
5b7b20d
Merge branch 'main' of https://github.com/y-hsgw/typescript-eslint in…
y-hsgw Mar 1, 2025
af4be16
test: add test
y-hsgw Mar 1, 2025
064f92d
Merge branch 'main' into fix/no-deprecated
y-hsgw Mar 2, 2025
3567212
test: add test for typeMatchesSomeSpecifier function
y-hsgw Mar 2, 2025
1cd8ea6
test: add test for valueMatchesSomeSpecifier function
y-hsgw Mar 2, 2025
3673d21
refactor: remove default empty array from specifiers
y-hsgw Mar 2, 2025
325e132
Revert "refactor: remove default empty array from specifiers"
y-hsgw Mar 13, 2025
767fc7a
test: add test case with undefined argument
y-hsgw Mar 13, 2025
e1c4670
Merge branch 'main' into fix/no-deprecated
y-hsgw Mar 13, 2025
54f820b
fix: sync workspace
y-hsgw Mar 13, 2025
3b3520b
feat: support PrivateIdentifier
y-hsgw Mar 21, 2025
0e61bcf
feat: support literal case
y-hsgw Apr 10, 2025
1578137
feat: support dynamic import
y-hsgw Apr 11, 2025
d65268c
test: add no-deprecated test
y-hsgw Apr 11, 2025
72641c0
fix: sync workspace
y-hsgw Apr 11, 2025
8fca2c2
Merge branch 'main' of https://github.com/y-hsgw/typescript-eslint in…
y-hsgw May 16, 2025
7e6b840
refactor: use named functions instead of string descriptions in descr…
y-hsgw May 16, 2025
8ef57d2
fix: lint fix
y-hsgw May 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion 6 packages/eslint-plugin/src/rules/no-deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
nullThrows,
typeOrValueSpecifiersSchema,
typeMatchesSomeSpecifier,
valueMatchesSomeSpecifier,
} from '../util';

type IdentifierLike =
Expand Down Expand Up @@ -375,7 +376,10 @@ export default createRule<Options, MessageIds>({
}

const type = services.getTypeAtLocation(node);
if (typeMatchesSomeSpecifier(type, allow, services.program)) {
if (
typeMatchesSomeSpecifier(type, allow, services.program) ||
valueMatchesSomeSpecifier(node, allow, services.program, type)
) {
return;
}

Expand Down
101 changes: 101 additions & 0 deletions 101 packages/eslint-plugin/tests/rules/no-deprecated.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,21 @@ ruleTester.run('no-deprecated', rule, {
{
code: `
/** @deprecated */
function A() {
return <div />;
}

const a = <A></A>;
`,
options: [
{
allow: [{ from: 'file', name: 'A' }],
},
],
},
{
code: `
/** @deprecated */
declare class A {}

new A();
Expand All @@ -344,7 +359,62 @@ new A();
},
{
code: `
/** @deprecated */
const deprecatedValue = 45;
const bar = deprecatedValue;
`,
options: [
{
allow: [{ from: 'file', name: 'deprecatedValue' }],
},
],
},
{
code: `
class MyClass {
/** @deprecated */
#privateProp = 42;
value = this.#privateProp;
}
`,
options: [
{
allow: [{ from: 'file', name: 'privateProp' }],
},
],
},
{
code: `
/** @deprecated */
const deprecatedValue = 45;
const bar = deprecatedValue;
`,
options: [
{
allow: ['deprecatedValue'],
},
],
},
{
code: `
import { exists } from 'fs';
exists('/foo');
`,
options: [
{
allow: [
{
from: 'package',
name: 'exists',
package: 'fs',
},
],
},
],
},
{
code: `
const { exists } = import('fs');
exists('/foo');
`,
options: [
Expand Down Expand Up @@ -2915,6 +2985,37 @@ class B extends A {
},
],
},
{
code: `
import { exists } from 'fs';
exists('/foo');
`,
errors: [
{
column: 1,
data: {
name: 'exists',
reason:
'Since v1.0.0 - Use {@link stat} or {@link access} instead.',
},
endColumn: 7,
endLine: 3,
line: 3,
messageId: 'deprecatedWithReason',
},
],
options: [
{
allow: [
{
from: 'package',
name: 'exists',
package: 'hoge',
},
],
},
],
},
{
code: `
declare class A {
Expand Down
68 changes: 68 additions & 0 deletions 68 packages/type-utils/src/TypeOrValueSpecifier.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { TSESTree } from '@typescript-eslint/types';
import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema';
import type * as ts from 'typescript';

import { AST_NODE_TYPES } from '@typescript-eslint/types';
import * as tsutils from 'ts-api-utils';

import { specifierNameMatches } from './typeOrValueSpecifiers/specifierNameMatches';
Expand Down Expand Up @@ -219,3 +221,69 @@ export const typeMatchesSomeSpecifier = (
program: ts.Program,
): boolean =>
specifiers.some(specifier => typeMatchesSpecifier(type, specifier, program));

const getSpecifierNames = (specifierName: string | string[]): string[] => {
return typeof specifierName === 'string' ? [specifierName] : specifierName;
};

const getStaticName = (node: TSESTree.Node): string | undefined => {
if (
node.type === AST_NODE_TYPES.Identifier ||
node.type === AST_NODE_TYPES.JSXIdentifier ||
node.type === AST_NODE_TYPES.PrivateIdentifier
) {
return node.name;
}

if (node.type === AST_NODE_TYPES.Literal && typeof node.value === 'string') {
return node.value;
}

return undefined;
};

export function valueMatchesSpecifier(
node: TSESTree.Node,
specifier: TypeOrValueSpecifier,
program: ts.Program,
type: ts.Type,
): boolean {
const staticName = getStaticName(node);
if (!staticName) {
return false;
}

if (typeof specifier === 'string') {
return specifier === staticName;
}

if (!getSpecifierNames(specifier.name).includes(staticName)) {
return false;
}

if (specifier.from === 'package') {
const symbol = type.getSymbol() ?? type.aliasSymbol;
const declarations = symbol?.getDeclarations() ?? [];
const declarationFiles = declarations.map(declaration =>
declaration.getSourceFile(),
);
return typeDeclaredInPackageDeclarationFile(
specifier.package,
declarations,
declarationFiles,
program,
);
}

return true;
}

export const valueMatchesSomeSpecifier = (
node: TSESTree.Node,
specifiers: TypeOrValueSpecifier[] = [],
program: ts.Program,
type: ts.Type,
): boolean =>
specifiers.some(specifier =>
valueMatchesSpecifier(node, specifier, program, type),
);
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.