-
Notifications
You must be signed in to change notification settings - Fork 109
Description
Adding to my previous real-world examples in #314 for constructors and factory methods, here's another pattern that I'm seeing a lot in our company's code: use of ternaries to handle the following pattern:
- Call some function
- If the function returns an expected value, perform some additional processing on the result
- If the function returns an unexpected value, return some fallback or default value, often
undefined
ornull
. - This process may continue through a longer pipeline
This interacts with TypeScript in a frustrating way, because unless you move the result of (1) into a temporary variable, TS doesn't know that calling the function again will result in the same value. So you need to cast or otherwise deal with the TS error. So even if the function's impact on perf is negligible, you still have to use a temp variable. ;-(
const qs = new URLSearchParams(url.split("?")[1] || "");
// before pipeline
qs.get("limit") ? parseInt(qs.get("limit"), 10) : undefined
// TS error: ^^^^^^^^^^^^^^^
// Argument of type 'string | null' is not assignable to parameter of type 'string'.
// Type 'null' is not assignable to type 'string'.ts(2345)
// with pipeline - no TS error
qs.get("limit") |> (% ? parseInt(%, 10) : undefined)
The reasons why temp variables are not ideal for this pattern are pretty much the same as #314: adding a new named variable .
This pattern would be made better by an optional pipe operator ?|>
(see #159) so multiple nullable pipes could be chained. But even without optional pipes, pipeline would make this pattern easier to use, esp. in TS apps.