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): fix crash and false positives inno-useless-default-assignment#11845

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
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

Some comments aren't visible on the classic Files Changed page.

View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,11 +39,6 @@ export default createRule<[], MessageId>({
create(context) {
const services = getParserServices(context);
const checker = services.program.getTypeChecker();
const compilerOptions = services.program.getCompilerOptions();
const isNoUncheckedIndexedAccess = tsutils.isCompilerOptionEnabled(
compilerOptions,
'noUncheckedIndexedAccess',
);

function canBeUndefined(type: ts.Type): boolean {
if (isTypeAnyType(type) || isTypeUnknownType(type)) {
Expand All@@ -60,10 +55,7 @@ export default createRule<[], MessageId>({
): ts.Type | null {
const symbol = objectType.getProperty(propertyName);
if (!symbol) {
if (isNoUncheckedIndexedAccess) {
return null;
}
return objectType.getStringIndexType() ?? null;
return null;
}
return checker.getTypeOfSymbol(symbol);
}
Expand All@@ -79,10 +71,6 @@ export default createRule<[], MessageId>({
}
}

if (isNoUncheckedIndexedAccess) {
return null;
}

return arrayType.getNumberIndexType() ?? null;
}

Expand DownExpand Up@@ -118,6 +106,13 @@ export default createRule<[], MessageId>({
}

const signatures = contextualType.getCallSignatures();
if (
signatures.length === 0 ||
signatures[0].getDeclaration() === tsFunc
) {
return;
}

const params = signatures[0].getParameters();
if (paramIndex < params.length) {
const paramSymbol = params[paramIndex];
Expand DownExpand Up@@ -152,12 +147,16 @@ export default createRule<[], MessageId>({
return;
}

const elementIndex = parent.elements.indexOf(node);
const elementType = getArrayElementType(sourceType, elementIndex);
if (!elementType) {
if (!checker.isTupleType(sourceType)) {
return;
}

const tupleArgs = checker.getTypeArguments(sourceType);
const elementIndex = parent.elements.indexOf(node);
if (elementIndex < 0 || elementIndex >= tupleArgs.length) {
return;
}
const elementType = tupleArgs[elementIndex];
if (!canBeUndefined(elementType)) {
reportUselessDefault(node, 'property', 'uselessDefaultAssignment');
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -184,6 +184,46 @@ ruleTester.run('no-useless-default-assignment', rule, {
},
},
},
`
declare const g: Array<string>;
const [foo = ''] = g;
`,
`
declare const g: Record<string, string>;
const { foo = '' } = g;
`,
`
declare const h: { [key: string]: string };
const { bar = '' } = h;
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/11849
`
type Merge = boolean | ((incoming: string[]) => void);

const policy: { merge: Merge } = {
merge: (incoming: string[] = []) => {
incoming;
},
};
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/11846
`
const [a, b = ''] = 'somestr'.split('.');
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/11846
`
declare const params: string[];
const [c = '123'] = params;
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/11846
`
declare function useCallback<T>(callback: T);
useCallback((value: number[] = []) => {});
`,
`
declare const tuple: [string];
const [a, b = 'default'] = tuple;

Choose a reason for hiding this comment

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

(praise) TIL that TS allows out-of-bounds tuple destructuring if a default value is present.

Comically it means that

const[a,outOfBounds=undefined]=["foo"]asconst;

iskind of a false positive if you really squint, but I think let's completely ignore that edge case as niche and unimportant.

ulrichstark and JoshuaKGoldberg reacted with thumbs up emoji
`,
],
invalid: [
{
Expand DownExpand Up@@ -459,62 +499,5 @@ ruleTester.run('no-useless-default-assignment', rule, {
function foo({ a }) {}
`,
},
{
code: `
declare const g: Record<string, string>;
const { hello = '' } = g;
`,
errors: [
{
column: 25,
data: { type: 'property' },
endColumn: 27,
line: 3,
messageId: 'uselessDefaultAssignment',
},
],
output: `
declare const g: Record<string, string>;
const { hello } = g;
`,
},
{
code: `
declare const h: { [key: string]: string };
const { world = '' } = h;
`,
errors: [
{
column: 25,
data: { type: 'property' },
endColumn: 27,
line: 3,
messageId: 'uselessDefaultAssignment',
},
],
output: `
declare const h: { [key: string]: string };
const { world } = h;
`,
},
{
code: `
declare const g: Array<string>;
const [foo = ''] = g;
`,
errors: [
{
column: 22,
data: { type: 'property' },
endColumn: 24,
line: 3,
messageId: 'uselessDefaultAssignment',
},
],
output: `
declare const g: Array<string>;
const [foo] = g;
`,
},
],
});

[8]ページ先頭

©2009-2025 Movatter.jp