@glint/template 1.0.0-beta.3 → 1.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,3 +47,20 @@ export declare function resolve<Args extends unknown[], Instance extends Invokab
47
47
  */
48
48
 
49
49
  export declare const resolveOrReturn: ResolveOrReturn<typeof resolve>;
50
+
51
+ /*
52
+ * Binding helpers like `{{component}}` and `{{helper}}` accept a variety of possible
53
+ * environment-specific initial arguments. This variant `resolve` signature allows
54
+ * environments to dictate how that argument is interpreted before being handed off to
55
+ * the actual helper definition. By resolving to the internal invokable form as described
56
+ * above, TypeScript can "do the right thing" in more cases for type inference, particularly
57
+ * with invokables whose signatures include type parameters.
58
+ */
59
+
60
+ export declare function resolveForBind<T extends DirectInvokable>(item: T): T[typeof InvokeDirect];
61
+ export declare function resolveForBind<Args extends unknown[], Instance extends InvokableInstance>(
62
+ item: abstract new (...args: Args) => Instance
63
+ ): (...args: Parameters<Instance[typeof Invoke]>) => ReturnType<Instance[typeof Invoke]>;
64
+ export declare function resolveForBind<Args extends unknown[], Instance extends InvokableInstance>(
65
+ item: null | undefined | (abstract new (...args: Args) => Instance)
66
+ ): null | ((...args: Parameters<Instance[typeof Invoke]>) => ReturnType<Instance[typeof Invoke]>);
@@ -15,6 +15,7 @@ import {
15
15
  InvokableArgs,
16
16
  MaybeNamed,
17
17
  PrebindArgs,
18
+ SliceFrom,
18
19
  } from './signature';
19
20
 
20
21
  /**
@@ -141,4 +142,44 @@ export type WithBoundArgs<
141
142
  >
142
143
  : never;
143
144
 
145
+ /**
146
+ * Similar to `WithBoundArgs`, this utility type provides a shorthand
147
+ * for specifying the type of a helper or modifier whose positional
148
+ * argument(s) have been pre-bound.
149
+ *
150
+ * Given the type of the helper or modifier in question and the number
151
+ * of positional arguments that have been pre-bound, this helper returns
152
+ * the same item back, but without those leading positional arguments.
153
+ *
154
+ * For instance, given a helper `FooHelper` with positional arg types
155
+ * `[secret: symbol, name: string, age: number]`, then if you wrote
156
+ * the following in a template:
157
+ *
158
+ * ```handlebars
159
+ * {{yield (helper FooHelper this.secret)}}
160
+ * ```
161
+ *
162
+ * You could represent that in your signature as:
163
+ *
164
+ * ```ts
165
+ * Blocks: {
166
+ * default: [WithBoundPositionals<typeof FooHelper, 1>];
167
+ * };
168
+ * ```
169
+ *
170
+ * Note that you can use `WithBoundPositionals` and `WithBoundArgs`
171
+ * together if you're pre-binding both positional and named arguments
172
+ * in the same location.
173
+ */
174
+ export type WithBoundPositionals<
175
+ T extends Invokable<AnyFunction> | AnyFunction,
176
+ Count extends number
177
+ > = T extends Invokable<(el: infer El, ...args: infer A) => ModifierReturn>
178
+ ? Invokable<(el: El, ...args: SliceFrom<A, Count>) => ModifierReturn>
179
+ : T extends Invokable<(...args: infer A) => infer R>
180
+ ? Invokable<(...args: SliceFrom<A, Count>) => R>
181
+ : T extends (...args: infer A) => infer R
182
+ ? Invokable<(...args: SliceFrom<A, Count>) => R>
183
+ : never;
184
+
144
185
  export {};
@@ -0,0 +1,99 @@
1
+ import { DirectInvokable, Invokable, NamedArgs, UnwrapNamedArgs } from '../integration';
2
+ import { MaybeNamed, PrebindArgs, SliceFrom, SliceTo } from '../signature';
3
+
4
+ type PrefixOf<T extends unknown[]> = T extends [arg: infer Arg, ...rest: infer Rest]
5
+ ? [] | [Arg, ...PrefixOf<Rest>]
6
+ : T;
7
+
8
+ export type BindInvokableKeyword<Prefix extends number, Kind> = DirectInvokable<{
9
+ // {{bind invokable}}
10
+ <Args extends unknown[], T extends Kind>(invokable: (...args: Args) => T): Invokable<
11
+ (...args: Args) => T
12
+ >;
13
+ <Args extends unknown[], T extends Kind>(
14
+ invokable: ((...args: Args) => T) | null | undefined
15
+ ): null | Invokable<(...args: Args) => T>;
16
+ // {{bind invokableWithOnlyNamedArgs name="foo"}}
17
+ <Named, Return extends Kind, GivenNamed>(
18
+ invokable: (named: NamedArgs<Named>) => Return,
19
+ named: NamedArgs<Partial<Named> & GivenNamed>
20
+ ): Invokable<
21
+ (
22
+ ...named: MaybeNamed<
23
+ PrebindArgs<NonNullable<Named>, keyof GivenNamed & keyof UnwrapNamedArgs<Named>>
24
+ >
25
+ ) => Return
26
+ >;
27
+ <Named, Return extends Kind, GivenNamed>(
28
+ invokable: null | undefined | ((named: NamedArgs<Named>) => Return),
29
+ named: NamedArgs<Partial<Named> & GivenNamed>
30
+ ): null | Invokable<
31
+ (
32
+ ...named: MaybeNamed<
33
+ PrebindArgs<NonNullable<Named>, keyof GivenNamed & keyof UnwrapNamedArgs<Named>>
34
+ >
35
+ ) => Return
36
+ >;
37
+ // {{bind invokableWithNamedAndPositionalArgs name="foo"}}
38
+ <Named, Positional extends unknown[], Return extends Kind, GivenNamed extends Partial<Named>>(
39
+ invokable: (...args: [...Positional, NamedArgs<Named>]) => Return,
40
+ named: GivenNamed
41
+ ): Invokable<
42
+ (
43
+ ...args: [
44
+ ...Positional,
45
+ ...MaybeNamed<
46
+ PrebindArgs<NonNullable<Named>, keyof GivenNamed & keyof UnwrapNamedArgs<Named>>
47
+ >
48
+ ]
49
+ ) => Return
50
+ >;
51
+ <Named, Positional extends unknown[], Return extends Kind, GivenNamed extends Partial<Named>>(
52
+ invokable: (...args: [...Positional, NamedArgs<Named>]) => Return,
53
+ named: GivenNamed
54
+ ): Invokable<
55
+ (
56
+ ...args: [
57
+ ...Positional,
58
+ ...MaybeNamed<
59
+ PrebindArgs<NonNullable<Named>, keyof GivenNamed & keyof UnwrapNamedArgs<Named>>
60
+ >
61
+ ]
62
+ ) => Return
63
+ >;
64
+ // {{bind invokable positional}}
65
+ <
66
+ Named,
67
+ Positional extends any[],
68
+ Return extends Kind,
69
+ GivenPositional extends PrefixOf<SliceFrom<Positional, Prefix>>
70
+ >(
71
+ invokable: (...args: [...Positional, NamedArgs<Named>]) => Return,
72
+ ...args: GivenPositional
73
+ ): Invokable<
74
+ (
75
+ ...args: [
76
+ ...SliceTo<Positional, Prefix>,
77
+ ...SliceFrom<SliceFrom<Positional, Prefix>, GivenPositional['length']>,
78
+ ...MaybeNamed<NamedArgs<Named>>
79
+ ]
80
+ ) => Return
81
+ >;
82
+ <
83
+ Named,
84
+ Positional extends any[],
85
+ Return extends Kind,
86
+ GivenPositional extends PrefixOf<SliceFrom<Positional, Prefix>>
87
+ >(
88
+ invokable: null | undefined | ((...args: [...Positional, NamedArgs<Named>]) => Return),
89
+ ...args: GivenPositional
90
+ ): null | Invokable<
91
+ (
92
+ ...args: [
93
+ ...SliceTo<Positional, Prefix>,
94
+ ...SliceFrom<SliceFrom<Positional, Prefix>, GivenPositional['length']>,
95
+ ...MaybeNamed<NamedArgs<Named>>
96
+ ]
97
+ ) => Return
98
+ >;
99
+ }>;
@@ -1,58 +1,4 @@
1
- import { WithBoundArgs } from '../index';
2
- import {
3
- ComponentReturn,
4
- DirectInvokable,
5
- InvokableInstance,
6
- NamedArgs,
7
- Invokable,
8
- NamedArgNames,
9
- AnyFunction,
10
- UnwrapNamedArgs,
11
- } from '../integration';
1
+ import { ComponentReturn } from '../integration';
2
+ import { BindInvokableKeyword } from './-bind-invokable';
12
3
 
13
- type PartiallyAppliedComponent<Component, Args> = Component extends Invokable<AnyFunction>
14
- ? WithBoundArgs<
15
- Component,
16
- Exclude<Args extends NamedArgNames<Component> ? Args : never, typeof NamedArgs>
17
- >
18
- : never;
19
-
20
- export type ComponentKeyword = DirectInvokable<{
21
- <
22
- Named,
23
- Positional extends unknown[],
24
- Return extends ComponentReturn<any, any>,
25
- ConstructorArgs extends unknown[],
26
- GivenArgs extends Partial<Named> = {}
27
- >(
28
- component: abstract new (...args: ConstructorArgs) => InvokableInstance<
29
- (...args: [...positional: Positional, named: Named]) => Return
30
- >,
31
- args?: NamedArgs<GivenArgs>
32
- ): PartiallyAppliedComponent<
33
- abstract new (...args: ConstructorArgs) => InvokableInstance<
34
- (...args: [...positional: Positional, named: Named]) => Return
35
- >,
36
- keyof UnwrapNamedArgs<GivenArgs>
37
- >;
38
- <
39
- Named,
40
- Positional extends unknown[],
41
- Return extends ComponentReturn<any, any>,
42
- ConstructorArgs extends unknown[],
43
- GivenArgs extends Partial<Named> = {}
44
- >(
45
- component:
46
- | null
47
- | undefined
48
- | (abstract new (...args: ConstructorArgs) => InvokableInstance<
49
- (...args: [...positional: Positional, named: Named]) => Return
50
- >),
51
- args?: NamedArgs<GivenArgs>
52
- ): null | PartiallyAppliedComponent<
53
- abstract new (...args: ConstructorArgs) => InvokableInstance<
54
- (...args: [...positional: Positional, named: Named]) => Return
55
- >,
56
- keyof UnwrapNamedArgs<GivenArgs>
57
- >;
58
- }>;
4
+ export type ComponentKeyword = BindInvokableKeyword<0, ComponentReturn<any, any>>;
@@ -0,0 +1,3 @@
1
+ import { BindInvokableKeyword } from './-bind-invokable';
2
+
3
+ export type HelperKeyword = BindInvokableKeyword<0, any>;
@@ -0,0 +1,4 @@
1
+ import { ModifierReturn } from '../integration';
2
+ import { BindInvokableKeyword } from './-bind-invokable';
3
+
4
+ export type ModifierKeyword = BindInvokableKeyword<1, ModifierReturn>;
@@ -3,6 +3,8 @@ export { DebuggerKeyword } from './keywords/debugger';
3
3
  export { EachKeyword } from './keywords/each';
4
4
  export { HasBlockKeyword } from './keywords/has-block';
5
5
  export { HasBlockParamsKeyword } from './keywords/has-block-params';
6
+ export { HelperKeyword } from './keywords/helper';
6
7
  export { InElementKeyword } from './keywords/in-element';
7
8
  export { LetKeyword } from './keywords/let';
9
+ export { ModifierKeyword } from './keywords/modifier';
8
10
  export { WithKeyword } from './keywords/with';
@@ -64,3 +64,20 @@ export type MaybeNamed<T> = T extends any
64
64
 
65
65
  export type Get<T, K, Otherwise = unknown> = K extends keyof T ? T[K] : Otherwise;
66
66
  export type Constrain<T, Constraint, Otherwise = Constraint> = T extends Constraint ? T : Otherwise;
67
+
68
+ export type TupleOfSize<Len extends number, Acc extends unknown[] = []> = Acc['length'] extends Len
69
+ ? Acc
70
+ : TupleOfSize<Len, [any, ...Acc]>;
71
+
72
+ export type SliceTo<T extends unknown[], Index extends number> = T['length'] extends Index
73
+ ? T
74
+ : T extends [...infer Rest, any?]
75
+ ? SliceTo<Rest, Index>
76
+ : [];
77
+
78
+ export type SliceFrom<T extends unknown[], Index extends number> = T extends [
79
+ ...TupleOfSize<Index>,
80
+ ...infer Rest
81
+ ]
82
+ ? Rest
83
+ : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glint/template",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
4
4
  "repository": "typed-ember/glint",
5
5
  "description": "Type definitions to back typechecking for Glimmer templates",
6
6
  "license": "MIT",