Skip to content

Commit

Permalink
fix(eslint-plugin): isTypeReadonly stack overflow (#5875) (#5876)
Browse files Browse the repository at this point in the history
Co-authored-by: Josh Goldberg <git@joshuakgoldberg.com>
  • Loading branch information
sviat9440 and JoshuaKGoldberg committed Nov 2, 2022
1 parent f11183c commit 2d9a33c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
Expand Up @@ -380,6 +380,27 @@ ruleTester.run('prefer-readonly-parameter-types', rule, {
},
],
},
{
name: 'circular readonly types (Bug: #5875)',
code: `
interface Obj1 {
readonly [K: string]: Obj2;
}
interface Obj2 {
readonly [K: string]: Obj1;
}
function foo(event: Obj1): void {}
`,
options: [
{
checkParameterProperties: true,
ignoreInferredTypes: false,
...readonlynessOptionsDefaults,
},
],
},
],
invalid: [
// arrays
Expand Down
2 changes: 1 addition & 1 deletion packages/type-utils/src/isTypeReadonly.ts
Expand Up @@ -113,7 +113,7 @@ function isTypeReadonlyObject(
return Readonlyness.Mutable;
}

if (indexInfo.type === type) {
if (indexInfo.type === type || seenTypes.has(indexInfo.type)) {
return Readonlyness.Readonly;
}

Expand Down
22 changes: 21 additions & 1 deletion packages/type-utils/tests/isTypeReadonly.test.ts
Expand Up @@ -139,6 +139,11 @@ describe('isTypeReadonly', () => {

it('handles circular readonly PropertySignature inside a readonly IndexSignature', () =>
runTests('interface Test { readonly [key: string]: Test };'));

it('handles circular readonly PropertySignature inside interdependent objects', () =>
runTests(
'interface Test1 { readonly [key: string]: Test } interface Test { readonly [key: string]: Test1 }',
));
});

describe('is not readonly', () => {
Expand All @@ -156,8 +161,23 @@ describe('isTypeReadonly', () => {
describe('is not readonly circular', () => {
const runTests = runTestIsNotReadonly;

it('handles circular mutable PropertySignature inside a readonly IndexSignature', () =>
it('handles circular mutable PropertySignature', () =>
runTests('interface Test { [key: string]: Test };'));

it.each([
[
'interface Test1 { [key: string]: Test } interface Test { readonly [key: string]: Test1 }',
],
[
'interface Test1 { readonly [key: string]: Test } interface Test { [key: string]: Test1 }',
],
[
'interface Test1 { [key: string]: Test } interface Test { [key: string]: Test1 }',
],
])(
'handles circular mutable PropertySignature inside interdependent objects',
runTests,
);
});
});

Expand Down

0 comments on commit 2d9a33c

Please sign in to comment.