Skip to content

Commit

Permalink
Merge pull request #188 from NullVoxPopuli/copy-pr-185
Browse files Browse the repository at this point in the history
Fix Glint types by converting helpers to plain functions
  • Loading branch information
SergeAstapov authored Sep 2, 2023
2 parents 0051908 + 9766373 commit d7e1640
Show file tree
Hide file tree
Showing 20 changed files with 170 additions and 694 deletions.
5 changes: 3 additions & 2 deletions packages/ember-truth-helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"scripts": {
"build": "concurrently 'npm:build:*'",
"build:js": "rollup --config",
"build:types": "glint --declaration && grep -r -l '///' declarations/ | sort | uniq | xargs perl -e \"s/\\/\\/\\/.*$//\" -pi",
"build:types": "glint --declaration",
"lint": "concurrently 'npm:lint:*(!fix)' --names 'lint:'",
"lint:fix": "concurrently 'npm:lint:*:fix' --names 'fix:'",
"lint:hbs": "ember-template-lint . --no-error-on-unmatched-pattern",
Expand All @@ -31,7 +31,8 @@
"prepack": "rollup --config"
},
"dependencies": {
"@embroider/addon-shim": "^1.8.6"
"@embroider/addon-shim": "^1.8.6",
"ember-functions-as-helper-polyfill": "^2.1.2"
},
"devDependencies": {
"@babel/core": "^7.22.9",
Expand Down
27 changes: 16 additions & 11 deletions packages/ember-truth-helpers/src/helpers/and.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { helper } from '@ember/component/helper';
import Helper from '@ember/component/helper';
import truthConvert from '../utils/truth-convert.ts';
import type { MaybeTruth } from '../utils/truth-convert.ts';

export interface AndSignature {
interface AndSignature<T extends unknown[]> {
Args: {
Positional: MaybeTruth[];
Positional: T;
};
Return: boolean;
Return: T[number];
}

export default helper<AndSignature>((params) => {
for (let i = 0, len = params.length; i < len; i++) {
if (truthConvert(params[i]) === false) {
return params[i] as boolean;
// We use class-based helper to ensure arguments are lazy-evaluated
// and helper short-circuits like native JavaScript `&&` (logical AND).
export default class AndHelper<T extends unknown[]> extends Helper<
AndSignature<T>
> {
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;
});
}
13 changes: 2 additions & 11 deletions packages/ember-truth-helpers/src/helpers/eq.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
import { helper } from '@ember/component/helper';

export interface EqSignature {
Args: {
Positional: [unknown, unknown];
};
Return: boolean;
export default function eq(left: unknown, right: unknown): boolean {
return left === right;
}

export default helper<EqSignature>((params) => {
return params[0] === params[1];
});
22 changes: 7 additions & 15 deletions packages/ember-truth-helpers/src/helpers/gt.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { helper } from '@ember/component/helper';

export interface GtSignature {
Args: {
Positional: [unknown, unknown];
Named: {
forceNumber?: boolean;
};
};
Return: boolean;
}

export default helper<GtSignature>(([left, right], options) => {
if (options.forceNumber) {
export default function gt(
left: unknown,
right: unknown,
options?: { forceNumber?: boolean }
) {
if (options?.forceNumber) {
if (typeof left !== 'number') {
left = Number(left);
}
Expand All @@ -20,4 +12,4 @@ export default helper<GtSignature>(([left, right], options) => {
}
}
return (left as number) > (right as number);
});
}
22 changes: 7 additions & 15 deletions packages/ember-truth-helpers/src/helpers/gte.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { helper } from '@ember/component/helper';

export interface GteSignature {
Args: {
Positional: [unknown, unknown];
Named: {
forceNumber?: boolean;
};
};
Return: boolean;
}

export default helper<GteSignature>(([left, right], options) => {
if (options.forceNumber) {
export default function gte(
left: unknown,
right: unknown,
options?: { forceNumber?: boolean }
) {
if (options?.forceNumber) {
if (typeof left !== 'number') {
left = Number(left);
}
Expand All @@ -20,4 +12,4 @@ export default helper<GteSignature>(([left, right], options) => {
}
}
return (left as number) >= (right as number);
});
}
15 changes: 3 additions & 12 deletions packages/ember-truth-helpers/src/helpers/is-array.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import { helper } from '@ember/component/helper';
import { isArray } from '@ember/array';
import type EmberArray from '@ember/array';
import { isArray as isEmberArray } from '@ember/array';

export interface IsArraySignature {
Args: {
Positional: unknown[] | EmberArray<unknown>;
};
Return: boolean;
export default function isArray(...params: unknown[]) {
return params.every(isEmberArray);
}

export default helper<IsArraySignature>((params) => {
return params.every(isArray);
});
12 changes: 1 addition & 11 deletions packages/ember-truth-helpers/src/helpers/is-empty.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
import { helper } from '@ember/component/helper';
import { isEmpty } from '@ember/utils';

export interface IsEmptySignature {
Args: {
Positional: [unknown];
};
Return: boolean;
}

export default helper<IsEmptySignature>(([obj]) => {
return isEmpty(obj);
});
export default isEmpty;
12 changes: 1 addition & 11 deletions packages/ember-truth-helpers/src/helpers/is-equal.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
import { helper } from '@ember/component/helper';
import { isEqual } from '@ember/utils';

export interface IsEqualSignature {
Args: {
Positional: [unknown, unknown];
};
Return: boolean;
}

export default helper<IsEqualSignature>(([a, b]) => {
return isEqual(a, b);
});
export default isEqual;
22 changes: 7 additions & 15 deletions packages/ember-truth-helpers/src/helpers/lt.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { helper } from '@ember/component/helper';

export interface LtSignature {
Args: {
Positional: [unknown, unknown];
Named: {
forceNumber?: boolean;
};
};
Return: boolean;
}

export default helper<LtSignature>(([left, right], options) => {
if (options.forceNumber) {
export default function lt(
left: unknown,
right: unknown,
options?: { forceNumber?: boolean }
) {
if (options?.forceNumber) {
if (typeof left !== 'number') {
left = Number(left);
}
Expand All @@ -20,4 +12,4 @@ export default helper<LtSignature>(([left, right], options) => {
}
}
return (left as number) < (right as number);
});
}
22 changes: 7 additions & 15 deletions packages/ember-truth-helpers/src/helpers/lte.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { helper } from '@ember/component/helper';

export interface LteSignature {
Args: {
Positional: [unknown, unknown];
Named: {
forceNumber?: boolean;
};
};
Return: boolean;
}

export default helper<LteSignature>(([left, right], options) => {
if (options.forceNumber) {
export default function lte(
left: unknown,
right: unknown,
options?: { forceNumber?: boolean }
) {
if (options?.forceNumber) {
if (typeof left !== 'number') {
left = Number(left);
}
Expand All @@ -20,4 +12,4 @@ export default helper<LteSignature>(([left, right], options) => {
}
}
return (left as number) <= (right as number);
});
}
13 changes: 2 additions & 11 deletions packages/ember-truth-helpers/src/helpers/not-eq.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
import { helper } from '@ember/component/helper';

export interface NotEqSignature {
Args: {
Positional: [unknown, unknown];
};
Return: boolean;
export default function notEq(left: unknown, right: unknown) {
return left !== right;
}

export default helper<NotEqSignature>((params) => {
return params[0] !== params[1];
});
12 changes: 2 additions & 10 deletions packages/ember-truth-helpers/src/helpers/not.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import { helper } from '@ember/component/helper';
import truthConvert from '../utils/truth-convert.ts';
import type { MaybeTruth } from '../utils/truth-convert.ts';

export interface NotSignature {
Args: {
Positional: MaybeTruth[];
};
Return: boolean;
}

export default helper<NotSignature>((params) => {
export default function not(...params: MaybeTruth[]) {
return params.every((param) => !truthConvert(param));
});
}
27 changes: 16 additions & 11 deletions packages/ember-truth-helpers/src/helpers/or.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { helper } from '@ember/component/helper';
import truthConvert from '../utils/truth-convert.ts';
import type { MaybeTruth } from '../utils/truth-convert.ts';
import Helper from '@ember/component/helper';

export interface OrSignature {
interface OrSignature<T extends unknown[]> {
Args: {
Positional: MaybeTruth[];
Positional: T;
};
Return: boolean;
Return: T[number];
}

export default helper<OrSignature>((params) => {
for (let i = 0, len = params.length; i < len; i++) {
if (truthConvert(params[i]) === true) {
return params[i] as boolean;
// We use class-based helper to ensure arguments are lazy-evaluated
// and helper short-circuits like native JavaScript `||` (logical OR).
export default class OrHelper<T extends unknown[]> extends Helper<
OrSignature<T>
> {
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 boolean;
});
}
12 changes: 2 additions & 10 deletions packages/ember-truth-helpers/src/helpers/xor.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { helper } from '@ember/component/helper';
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);
}

export default helper<XorSignature>((params) => {
return truthConvert(params[0]) !== truthConvert(params[1]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
{{log @andArg}}
{{log @orArg}}
</div>
19 changes: 19 additions & 0 deletions packages/modern-test-app/app/components/and-or-type-checking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import templateOnly from '@ember/component/template-only';

interface Signature {
Element: HTMLDivElement;
Args: {
andArg: object | boolean;
orArg: object | boolean;
};
}

const AndOrTypeChecking = templateOnly<Signature>();

export default AndOrTypeChecking;

declare module '@glint/environment-ember-loose/registry' {
export default interface Registry {
AndOrTypeChecking: typeof AndOrTypeChecking;
}
}
7 changes: 6 additions & 1 deletion packages/modern-test-app/app/templates/helpers.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@
{{not-eq 6 5}}
{{not true}}
{{or true false}}
{{xor true false}}
{{xor true false}}

<AndOrTypeChecking
@andArg={{or (hash) (array)}}
@orArg={{and (hash) (array)}}
/>
18 changes: 18 additions & 0 deletions packages/test-app/tests/unit/helpers/and-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,22 @@ module('helper:and', function (hooks) {

assert.equal(this.element.textContent, '[2]', 'value should be "[2]"');
});

test('it does short-circuit with falsey argument', async function (assert) {
this.foo = {
get bar() {
assert.step('get bar');
return false;
},
get baz() {
assert.step('get baz');
return true;
},
};

await render(hbs`[{{and this.foo.bar this.foo.baz}}]`);

assert.verifySteps(['get bar']);
assert.dom().hasText('[false]');
});
});
Loading

0 comments on commit d7e1640

Please sign in to comment.