Skip to content

Commit

Permalink
Merge pull request #76 from typed-ember/ambiguous-glimmerx-function
Browse files Browse the repository at this point in the history
Interpret functions that accept `unknown` in GlimmerX as helpers, not modifiers
  • Loading branch information
dfreeman authored Mar 22, 2021
2 parents 74de8d1 + 95126c9 commit d2764a5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/environment-glimmerx/-private/dsl/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export declare function resolve<Args extends unknown[], Instance extends Invokab
export declare function resolve<Value, Args extends unknown[], T extends Value>(
item: (value: Value, ...args: Args) => value is T
): (named: EmptyObject, value: Value, ...args: Args) => value is T;
export declare function resolve<Args extends unknown[], T>(
item: (arg: unknown, ...args: Args) => T
): (named: EmptyObject, arg: unknown, ...args: Args) => T;
export declare function resolve<El extends Element, Args extends unknown[]>(
item: (element: El, ...args: Args) => void | (() => void)
): (named: EmptyObject, ...args: Args) => BoundModifier<El>;
Expand Down
16 changes: 15 additions & 1 deletion packages/environment-glimmerx/__tests__/helper.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { resolve } from '@glint/environment-glimmerx/-private/dsl';
import { invokeEmit, resolve } from '@glint/environment-glimmerx/-private/dsl';
import { helper, fn as fnDefinition } from '@glint/environment-glimmerx/helper';
import { EmptyObject } from '@glint/template/-private/integration';
import { expectTypeOf } from 'expect-type';
Expand Down Expand Up @@ -108,3 +108,17 @@ import { expectTypeOf } from 'expect-type';
expectTypeOf(x).toEqualTypeOf<number>();
}
}

// Custom helper that accepts `unknown`
// (and therefore plausibly could be interpreted as a modifier, but shouldn't be)
{
let definition = (_arg: unknown, callback: () => void): void => callback();

let hackyOnChange = resolve(definition);

expectTypeOf(hackyOnChange).toEqualTypeOf<
(named: EmptyObject, arg: unknown, callback: () => void) => void
>();

invokeEmit(hackyOnChange({}, 'hello', () => console.log('change!')));
}
16 changes: 16 additions & 0 deletions packages/environment-glimmerx/__tests__/modifier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,19 @@ import { expectTypeOf } from 'expect-type';

expectTypeOf(applyModifier(on({}, 'click', () => {}))).toEqualTypeOf<void>();
}

// Custom modifier with a specific element type
{
const fetchImageData = resolve(
(element: HTMLImageElement, callback: (data: ImageData | undefined) => void): void => {
let context = document.createElement('canvas').getContext('2d');
context?.drawImage(element, 0, 0);
callback(context?.getImageData(0, 0, element.naturalWidth, element.naturalHeight));
}
);

applyModifier<HTMLImageElement>(fetchImageData({}, (data) => console.log(data)));

// @ts-expect-error: invalid element type
applyModifier<HTMLDivElement>(fetchImageData({}, (data) => console.log(data)));
}

0 comments on commit d2764a5

Please sign in to comment.