Open Roanmh opened 2 weeks ago
When you use the native Array.prototype.filter() function on a union type (like Fizz[] | Buzz[]), TypeScript is more lenient and tries to infer the type based on the structural typing principle. Structural typing means that TypeScript checks if a type has the necessary properties at runtime, rather than enforcing strict type rules upfront.
TypeScript assumes that both Fizz and Buzz might have an id property, and it allows you to proceed without throwing an error. This leniency can lead to runtime errors if one of the types (e.g., Buzz) doesn't actually have the id property.
Lodash’s TypeScript type definitions are stricter because they want to ensure you don’t encounter runtime issues by accidentally accessing properties that don't exist on certain types. So you can use something like:
interface Common { id: number; }
interface Fizz extends Common { // Other properties for Fizz }
interface Buzz extends Common { // Other properties for Buzz }
_.filter([] as Fizz[] | Buzz[]).filter(item => item.id < 5);
Now _filter can be sure that both Fizz and Buzz has a id property.
The following code errors for lodash but not for the similar implementation using the built in
.filter()
. I encountered this, but my minimal repro is inspired by @ialexryan 's report of microsoft/TypeScript#44373. This is also true forfind
,every
,some
, etcor view on TS Playground
Note: Typescript would error as well until this was fixed by Typescript 5.2.2