Skip to content

Commit

Permalink
fix(eslint-plugin): [no-unnecessary-condition] fix false positive wit…
Browse files Browse the repository at this point in the history
…h computed member access and branded key type
  • Loading branch information
yf-yang committed Sep 30, 2023
1 parent 4a6d841 commit de4ae83
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
9 changes: 3 additions & 6 deletions packages/eslint-plugin/src/rules/no-unnecessary-condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,12 +534,9 @@ export default createRule<Options, MessageId>({
}
}
const typeName = getTypeName(checker, propertyType);
return !!(
(typeName === 'string' &&
checker.getIndexInfoOfType(objType, ts.IndexKind.String)) ||
(typeName === 'number' &&
checker.getIndexInfoOfType(objType, ts.IndexKind.Number))
);
return !!checker
.getIndexInfosOfType(objType)
.find(info => getTypeName(checker, info.keyType) === typeName);
}

// Checks whether a member expression is nullable or not regardless of it's previous node.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,53 @@ type Key = 'bar' | 'foo' | 'baz';
declare const foo: Foo;
declare const key: Key;
foo?.[key]?.trim();
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/7700
`
type BrandedKey = string & { __brand: string };
type Foo = { [key: BrandedKey]: string } | null;
declare const foo: Foo;
const key = '1' as BrandedKey;
foo?.[key]?.trim();
`,
`
type BrandedKey<S extends string> = S & { __brand: string };
type Foo = { [key: string]: string; foo: 'foo'; bar: 'bar' } | null;
type Key = Branded<'bar'> | Branded<'foo'>;
declare const foo: Foo;
declare const key: Key;
foo?.[key].trim();
`,
`
type BrandedKey = string & { __brand: string };
interface Outer {
inner?: {
[key: BrandedKey<string>]: string | undefined;
};
}
function Foo(outer: Outer, key: BrandedKey): number | undefined {
return outer.inner?.[key]?.charCodeAt(0);
}
`,
`
interface Outer {
inner?: {
[key: string & { __brand: string }]: string | undefined;
bar: 'bar';
};
}
type Foo = 'foo' & { __brand: string };
function Foo(outer: Outer, key: Foo): number | undefined {
return outer.inner?.[key]?.charCodeAt(0);
}
`,
`
type BrandedKey<S extends string> = S & { __brand: string };
type Foo = { [key: string]: string; foo: 'foo'; bar: 'bar' } | null;
type Key = BrandedKey<'bar'> | BrandedKey<'foo'> | BrandedKey<'baz'>;
declare const foo: Foo;
declare const key: Key;
foo?.[key]?.trim();
`,
`
Expand Down

0 comments on commit de4ae83

Please sign in to comment.