> filter doesn't even change the types of its arguments

But map, which 90% is used after filter, does.

  const foo = client.someRequest()
    .filter(item => /* some condition */)
    .map(item => /* some transformation */)

  someFunction(foo)
Without a strong type system, how do you ensure "someFunction" is called with the correct data structure ?

The answer is either:

  - you implement your own type system (based on json schema?)
  - you write the type checks manually in your tests
With a strong type system, it is already done by the compiler.

Every REST/GraphQL APIs relies on a strongly typed schema.

A type system in your programming language is a feature that allows you to "encode" the schema within the language itself.

The most expressive the type system is, the less validation code you need. The less code you have, the easier it is to maintain your code.

You don't like the verbosity? That's what type inference is for, take a look at that Typescript example:

  const handlers = {
    foo: () => { /* ... */ },
    bar: () => { /* ... */ }
  }
  const action: keyof typeof handlers = someOtherFunc()
  handlers[action]()
If your function returns just a string, Typescript would scream at you. If your function return type is ('foo' | 'bar'), then you ensure that handlers[action] will never be undefined, without writing an if/else/throw block.