eslint-plugin-unicorn icon indicating copy to clipboard operation
eslint-plugin-unicorn copied to clipboard

`prefer-native-coercion-functions` should ignore type guards

Open JacobLey opened this issue 2 years ago • 4 comments

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.

JacobLey avatar Jul 13 '22 16:07 JacobLey

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 avatar Jan 28 '23 07:01 fregante

related: there's a request in TypeScript to use boolean as a type guard: https://github.com/microsoft/TypeScript/issues/16069

carmanchris31 avatar Oct 10 '23 16:10 carmanchris31

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.

leppaott avatar Feb 22 '24 12:02 leppaott

For those curious, the underlying TypeScript feature to assert types from boolean coercion functions has been implemented and will be released in TypeScript 5.5: https://github.com/microsoft/TypeScript/pull/57465#issuecomment-2016987675

lachieh avatar Apr 18 '24 14:04 lachieh