Help me simplify this nested ternary expression with ts-pattern
#216
-
I came across this library recently, and while I did understand the examples I do not fully understand the extensive use cases. In my code I have this complex ternary expression and I wanted to know if with The code: type FilterProperty = 'Availablity' | 'Location' | 'Date'
let existingFilterProperties: FilterProperty[] = [];
let existingSharedFilterProperties: FilterProperty[] = [];
let addFilterAction = false;
let activeFilter: {property: FilterProperty, share: boolean, value: string} | {} = {};
function getFilteredProperties(properties: FilterProperty[]) {
return properties
.filter((property) =>
!addFilterAction
? activeFilter.share
? property !== 'Date'
: true
: property === 'Date'
? !existingFilterProperties.includes(property)
: !(
existingFilterProperties.includes(property) &&
existingSharedFilterProperties.includes(property)
),
)
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
If you really want to, you can use tuples to perform nested matching. However, TS Pattern can struggle with the relations; a value may not be relevant if another value is not true, but TS Pattern will want you to check that combination anyway. Effectively, you are abusing parallel matching for testing nested conditions. For example, I believe this should have the same behavior as your original code: function getFilteredProperties(properties: FilterProperty[]) {
return properties.filter((property) =>
match([addFilterAction, activeFilter, property])
.with([false, { share: true }, "Date"], () => false)
.with([false, { share: true }, P.not("Date")], () => true)
.with([false, P.any, P.any], () => true)
.with(
[true, P.any, "Date"],
() => !existingFilterProperties.includes("Date"),
)
.with(
[true, P.any, P.not("Date").select()],
(property) =>
!(
existingFilterProperties.includes(property) &&
existingSharedFilterProperties.includes(property)
),
)
.exhaustive(),
)
} Note that you need to include global variables in the input if you use them in patterns. You can also use multiple matchers, instead of abusing a single one. However, this may end up being more complex than the original. function getFilteredProperties(properties: FilterProperty[]) {
return properties.filter((property) =>
addFilterAction
? property === "Date"
? !existingFilterProperties.includes(property)
: !(
existingFilterProperties.includes(property) &&
existingSharedFilterProperties.includes(property)
)
: match([activeFilter, property])
.with([{ share: true }, "Date"], () => false)
.with([{ share: true }, P.not("Date")], () => true)
.with([P.any, P.any], () => true)
.exhaustive(),
)
} Whether this is any simpler or worth it is subjective. |
Beta Was this translation helpful? Give feedback.
If you really want to, you can use tuples to perform nested matching. However, TS Pattern can struggle with the relations; a value may not be relevant if another value is not true, but TS Pattern will want you to check that combination anyway. Effectively, you are abusing parallel matching for testing nested conditions.
For example, I believe this should have the same behavior as your original code: