From 2042defc7f23c19006512b3bc332bdff0f89dee4 Mon Sep 17 00:00:00 2001 From: Sergey Astapov Date: Thu, 31 Aug 2023 14:11:23 -0400 Subject: [PATCH] make `and` and `or` helpers class based that way, we preserve semantic of them lazily evaluating arguments and able to accept generics --- .../ember-truth-helpers/src/helpers/and.ts | 23 ++++++++--- .../ember-truth-helpers/src/helpers/or.ts | 41 ++++++++----------- .../ember-truth-helpers/src/helpers/xor.ts | 7 ---- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/packages/ember-truth-helpers/src/helpers/and.ts b/packages/ember-truth-helpers/src/helpers/and.ts index b6849eb..589c596 100644 --- a/packages/ember-truth-helpers/src/helpers/and.ts +++ b/packages/ember-truth-helpers/src/helpers/and.ts @@ -1,11 +1,22 @@ +import Helper from '@ember/component/helper'; import truthConvert from '../utils/truth-convert.ts'; -import type { MaybeTruth } from '../utils/truth-convert.ts'; -export default function and(...params: [...T]) { - for (let i = 0, len = params.length; i < len; i++) { - if (truthConvert(params[i]) === false) { - return params[i] as boolean; +interface AndSignature { + Args: { + Positional: T; + }; + Return: T[number]; +} + +export default class AndHelper extends Helper< + AndSignature +> { + public compute(params: T): T[number] { + for (let i = 0, len = params.length; i < len; i++) { + if (truthConvert(params[i]) === false) { + return params[i]; + } } + return params[params.length - 1]; } - return params[params.length - 1] as boolean; } diff --git a/packages/ember-truth-helpers/src/helpers/or.ts b/packages/ember-truth-helpers/src/helpers/or.ts index 5bc8fdf..937970f 100644 --- a/packages/ember-truth-helpers/src/helpers/or.ts +++ b/packages/ember-truth-helpers/src/helpers/or.ts @@ -1,29 +1,22 @@ import truthConvert from '../utils/truth-convert.ts'; -import type { MaybeTruth } from '../utils/truth-convert.ts'; +import Helper from '@ember/component/helper'; -export default function or(...params: [...T]) { - for (let i = 0, len = params.length; i < len; i++) { - if (truthConvert(params[i]) === true) { - return params[i] as FirstNonFalsy; +interface OrSignature { + Args: { + Positional: T; + }; + Return: T[number]; +} + +export default class OrHelper extends Helper< + OrSignature +> { + public compute(params: T): T[number] { + for (let i = 0, len = params.length; i < len; i++) { + if (truthConvert(params[i]) === true) { + return params[i]; + } } + return params[params.length - 1]; } - return params[params.length - 1] as Last; } - -type FirstNonFalsy = T extends [infer K] - ? K - : T extends [infer A, ...infer R] - ? Truthy extends true - ? A - : FirstNonFalsy - : never; - -type Last = T extends [infer K] - ? K - : T extends [...infer Q, infer L] - ? L - : never; - -type Truthy = T extends Falsy ? false : true; - -type Falsy = false | 0 | '' | null | undefined | { isTruthy: false } | []; diff --git a/packages/ember-truth-helpers/src/helpers/xor.ts b/packages/ember-truth-helpers/src/helpers/xor.ts index 96791db..d3c0391 100644 --- a/packages/ember-truth-helpers/src/helpers/xor.ts +++ b/packages/ember-truth-helpers/src/helpers/xor.ts @@ -1,12 +1,5 @@ import truthConvert from '../utils/truth-convert.ts'; -export interface XorSignature { - Args: { - Positional: [unknown, unknown]; - }; - Return: boolean; -} - export default function xor(left: unknown, right: unknown) { return truthConvert(left) !== truthConvert(right); }