Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

fix(eslint-plugin): [unified-signatures] exemptthis from optional parameter overload check#11005

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
37 changes: 37 additions & 0 deletionspackages/eslint-plugin/src/rules/unified-signatures.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -264,6 +264,14 @@ export default createRule<Options, MessageIds>({
types1: readonly TSESTree.Parameter[],
types2: readonly TSESTree.Parameter[],
): Unify | undefined {
const firstParam1 = types1[0];
const firstParam2 = types2[0];

// exempt signatures with `this: void` from the rule
if (isThisVoidParam(firstParam1) || isThisVoidParam(firstParam2)) {
return undefined;
}

const index = getIndexOfFirstDifference(
types1,
types2,
Expand DownExpand Up@@ -294,6 +302,22 @@ export default createRule<Options, MessageIds>({
: undefined;
}

function isThisParam(param: TSESTree.Parameter | undefined): boolean {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

FYI/PSA - I changed this not to be a type predicate since it's only valid in thetrue branch, not thefalse branch (the function returningfalse does not imply thatparam isnot aTSESTree.Identifier).

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Oh I didn't think about TS doing a negative refinement when the function returnsfalse. It would be useful to be able to declare an assertion that only refines in thetrue case

kirkwaiblinger reacted with thumbs up emoji
return (
param != null &&
param.type === AST_NODE_TYPES.Identifier &&
param.name === 'this'
);
}

function isThisVoidParam(param: TSESTree.Parameter | undefined) {
return (
isThisParam(param) &&
(param as TSESTree.Identifier).typeAnnotation?.typeAnnotation.type ===
AST_NODE_TYPES.TSVoidKeyword
);
}

/**
* Detect `a(): void` and `a(x: number): void`.
* Returns the parameter declaration (`x: number` in this example) that should be optional/rest, and overload it's a part of.
Expand All@@ -310,6 +334,19 @@ export default createRule<Options, MessageIds>({
const shorter = sig1.length < sig2.length ? sig1 : sig2;
const shorterSig = sig1.length < sig2.length ? a : b;

const firstParam1 = sig1.at(0);
const firstParam2 = sig2.at(0);
// If one signature has explicit this type and another doesn't, they can't
// be unified.
if (isThisParam(firstParam1) !== isThisParam(firstParam2)) {
return undefined;
}

// exempt signatures with `this: void` from the rule
if (isThisVoidParam(firstParam1) || isThisVoidParam(firstParam2)) {
return undefined;
}

// If one is has 2+ parameters more than the other, they must all be optional/rest.
// Differ by optional parameters: f() and f(x), f() and f(x, ?y, ...z)
// Not allowed: f() and f(x, y)
Expand Down
83 changes: 83 additions & 0 deletionspackages/eslint-plugin/tests/rules/unified-signatures.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -380,6 +380,21 @@ declare function f(x: boolean): unknown;
`,
options: [{ ignoreOverloadsWithDifferentJSDoc: true }],
},
`
function f(): void;
function f(this: {}): void;
function f(this: void | {}): void {}
`,
`
function f(a: boolean): void;
function f(this: {}, a: boolean): void;
function f(this: void | {}, a: boolean): void {}
`,
`
function f(this: void, a: boolean): void;
function f(this: {}, a: boolean): void;
function f(this: void | {}, a: boolean): void {}
`,
],
invalid: [
{
Expand DownExpand Up@@ -1136,5 +1151,73 @@ declare function f(x: boolean): unknown;
],
options: [{ ignoreOverloadsWithDifferentJSDoc: true }],
},
{
code: `
function f(this: {}, a: boolean): void;
function f(this: {}, a: string): void;
function f(this: {}, a: boolean | string): void {}
`,
errors: [
{
column: 22,
line: 3,
messageId: 'singleParameterDifference',
},
],
},
{
code: `
function f(this: {}): void;
function f(this: {}, a: string): void;
function f(this: {}, a?: string): void {}
`,
errors: [
{
column: 22,
line: 3,
messageId: 'omittingSingleParameter',
},
],
},
{
code: `
function f(this: string): void;
function f(this: number): void;
function f(this: string | number): void {}
`,
errors: [
{
column: 12,
data: {
failureStringStart:
'These overloads can be combined into one signature',
type1: 'string',
type2: 'number',
},
line: 3,
messageId: 'singleParameterDifference',
},
],
},
{
code: `
function f(this: string, a: boolean): void;
function f(this: number, a: boolean): void;
function f(this: string | number, a: boolean): void {}
`,
errors: [
{
column: 12,
data: {
failureStringStart:
'These overloads can be combined into one signature',
type1: 'string',
type2: 'number',
},
line: 3,
messageId: 'singleParameterDifference',
},
],
},
],
});

[8]ページ先頭

©2009-2025 Movatter.jp