Skip to content
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

prefer-native-coercion-functions should ignore type guards #1857

Open
JacobLey opened this issue Jul 13, 2022 · 8 comments
Open

prefer-native-coercion-functions should ignore type guards #1857

JacobLey opened this issue Jul 13, 2022 · 8 comments

Comments

@JacobLey
Copy link

JacobLey commented Jul 13, 2022

prefer-native-coercion-functions is used to simplify methods like filter that are simply trying to find truthy values. However the native type castings do not provide any typescript assertions, so the resulting type of the filter is unchanged. When manually providing these assertions, prefer-native-coercion-functions should not suggest a native coercion over the manual callback.

prefer-native-coercion-functions

const mixedData: (string | null)[] = ['abc', '', null, 'xyz'];

// Eslint is happy, but `null` is not removed from type
const untypedMixedData: (string | null)[] = mixedData.filter(Boolean);

// Eslint is unhappy, but `null` is removed from type
const typedMixedData: string[] = mixedData.filter((d): d is string => Boolean(d));

Ideally that second example is ignored by this eslint rule because the custom assertions provide context that the native coercion function does not.


Alternatively the resulting array can just be manually typed casted, but I would argue that typescript's default typings via assertions is preferred.

const castMixedData: string[] = mixedData.filter(Boolean) as string[];

Similarly I could provide some method like isTruthy

const isTruthy = (x: unknown): x is string | number | symbol | object | unknown[] => Boolean(x);
const isTruthyData = mixedData.filter(isTruthy);

but that will interfere with no-array-callback-reference.

@fregante fregante changed the title prefer-native-coercion-functions should ignore typed assertion filters prefer-native-coercion-functions should ignore type guards Jan 28, 2023
@fregante
Copy link
Collaborator

I agree that this should work:

const mixedData: (string | null)[] = ['abc', '', null, 'xyz'];

// Eslint is unhappy, but `null` is removed from type
const typedMixedData: string[] = mixedData.filter((d): d is string => Boolean(d));

Similarly I could provide some method like isTruthy

Note that this example however is wrong, isTruthy(true) asserts that true is string | number | symbol | object | unknown[], which it isn't

@fregante fregante added the bug label Jan 28, 2023
@carmanchris31
Copy link

related: there's a request in TypeScript to use boolean as a type guard: microsoft/TypeScript#16069

@fregante fregante added the types Issues that happen in TypeScript or that require types label Feb 10, 2024
@leppaott
Copy link

Would be nice to have this ignore ones with type guards if possible indeed because the rule seems useful. There seems to be a new PR to fix this on TS but it's been years and years so could be good to fix this for older TS versions.

@lachieh

This comment was marked as outdated.

@fregante

This comment was marked as outdated.

@fregante fregante closed this as not planned Won't fix, can't repro, duplicate, stale Sep 4, 2024
@leppaott
Copy link

leppaott commented Sep 4, 2024

@fregante what do you mean microsoft/TypeScript#57465 (comment) .filter(Boolean) doesn't work it has to be .filter((uuid) => uuid !== undefined) or .filter((uuid) => uuid !== null) to have narrowing working. I'm hoping they get it working later because that's a pretty common use-case indeed. We have TS 5.5.4.

@fregante fregante reopened this Sep 4, 2024
@fregante fregante added help wanted and removed types Issues that happen in TypeScript or that require types labels Sep 4, 2024
@lachieh
Copy link

lachieh commented Sep 4, 2024

Yeah, that's my bad. This is the issue to track: microsoft/TypeScript#16655

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants