Skip to content

Commit

Permalink
Merge pull request #398 from glimmerjs/fix-expand-signature
Browse files Browse the repository at this point in the history
Fix ExpandSignature & ArgsFor
  • Loading branch information
chadhietala committed Sep 6, 2022
2 parents 4707c1c + aeb1213 commit 81e726a
Showing 1 changed file with 12 additions and 9 deletions.
21 changes: 12 additions & 9 deletions packages/@glimmer/component/addon/-private/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function setDestroyed(component: GlimmerComponent<object>): void {
interface ArgsSetMap extends WeakMap<Args<unknown>, boolean> {
get<S>(key: Args<S>): boolean | undefined;
set<S>(key: Args<S>, value: boolean): this;
has<S>(key: Args<S>): boolean;
}

// SAFETY: this only holds because we *only* acces this when `DEBUG` is `true`.
Expand Down Expand Up @@ -48,11 +49,13 @@ declare const Empty: unique symbol;
*/
export type EmptyObject = { [Empty]?: true };

type GetOrElse<Obj, K, Fallback> = K extends keyof Obj ? Obj[K] : Fallback;
type GetOrElse<Obj, K extends PropertyKey, Fallback> = Obj extends { [Key in K]: infer U }
? U
: Fallback;

/** Given a signature `S`, get back the `Args` type. */
type ArgsFor<S> = 'Args' extends keyof S
? S['Args'] extends { Named?: object; Positional?: unknown[] } // Are they longhand already?
type ArgsFor<S> = S extends { Args: infer Args }
? Args extends { Named?: object; Positional?: unknown[] } // Are they longhand already?
? {
Named: GetOrElse<S['Args'], 'Named', EmptyObject>;
Positional: GetOrElse<S['Args'], 'Positional', []>;
Expand All @@ -65,11 +68,11 @@ type _ExpandSignature<T> = {
Args: keyof T extends 'Args' | 'Element' | 'Blocks' // Is this a `Signature`?
? ArgsFor<T> // Then use `Signature` args
: { Named: T; Positional: [] }; // Otherwise fall back to classic `Args`.
Blocks: 'Blocks' extends keyof T
Blocks: T extends { Blocks: infer Blocks }
? {
[Block in keyof T['Blocks']]: T['Blocks'][Block] extends unknown[]
? { Params: { Positional: T['Blocks'][Block] } }
: T['Blocks'][Block];
[Block in keyof Blocks]: Blocks[Block] extends unknown[]
? { Params: { Positional: Blocks[Block] } }
: Blocks[Block];
}
: EmptyObject;
};
Expand Down Expand Up @@ -230,8 +233,8 @@ export default class GlimmerComponent<S = unknown> {
* @param owner
* @param args
*/
constructor(_owner: unknown, args: Args<S>) {
if (DEBUG && !ARGS_SET.has(args)) {
constructor(owner: unknown, args: Args<S>) {
if (DEBUG && !(owner !== null && typeof owner === 'object' && ARGS_SET.has(args))) {
throw new Error(
`You must pass both the owner and args to super() in your component: ${this.constructor.name}. You can pass them directly, or use ...arguments to pass all arguments through.`
);
Expand Down

0 comments on commit 81e726a

Please sign in to comment.