-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #148 from dfreeman/extensible-types
Update types for extensibility
- Loading branch information
Showing
11 changed files
with
135 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,21 @@ | ||
import { default as Component } from '@glimmer/component'; | ||
|
||
export { default } from '@glimmer/component'; | ||
export { tracked } from '@glimmer/tracking'; | ||
|
||
export function hbs(_strings: TemplateStringsArray): Component { | ||
// This type exists to provide a non-user-constructible, non-subclassable | ||
// type representing the conceptual "instance type" of a template-only component. | ||
// The abstract field of type `never` prevents subclassing in userspace of | ||
// the value returned from `hbs`. | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
export declare abstract class TemplateComponentInstance<S> { | ||
protected abstract __concrete__: never; | ||
} | ||
|
||
// By making `TemplateComponent` abstract and impossible to subclass | ||
// (see above), we prevent users from attempting to instantiate a the | ||
// return value of `hbs` themselves, while leaving a hook for tools | ||
// like Glint to augment the type. | ||
export type TemplateComponent<S> = abstract new () => TemplateComponentInstance<S>; | ||
|
||
export function hbs<S>(_strings: TemplateStringsArray): TemplateComponent<S> { | ||
throw new Error('hbs template should have been compiled at build time'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,13 @@ | ||
export { helper, Helper } from './src/helper'; | ||
export { fn } from '@glimmer/helper'; | ||
export { helper, HelperFunction, Helper } from './src/helper'; | ||
|
||
import { fn as glimmerFn } from '@glimmer/helper'; | ||
|
||
declare const Brand: unique symbol; | ||
|
||
// This interface provides an extension point for tools like | ||
// Glint to augment with template-specific type information. | ||
export interface FnHelper { | ||
[Brand]: 'helper:fn'; | ||
} | ||
|
||
export const fn = glimmerFn as FnHelper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,13 @@ | ||
export { on, action } from '@glimmer/modifier'; | ||
import { action, on as glimmerOn } from '@glimmer/modifier'; | ||
|
||
declare const Brand: unique symbol; | ||
|
||
// This interface provides an extension point for tools like | ||
// Glint to augment with template-specific type information. | ||
export interface OnModifier { | ||
[Brand]: 'modifier:on'; | ||
} | ||
|
||
const on = glimmerOn as OnModifier; | ||
|
||
export { on, action }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { expectTypeOf } from 'expect-type'; | ||
import { hbs, TemplateComponent } from '@glimmerx/component'; | ||
|
||
declare module '@glimmerx/component' { | ||
// For the purposes of testing, make the instance type dependent on the `S` parameter, | ||
// even if in practice the variance wouldn't be quite right. | ||
export interface TemplateComponentInstance<S> { | ||
value: S; | ||
} | ||
} | ||
|
||
type SignatureOf<T> = T extends TemplateComponent<infer S> ? S : unknown; | ||
|
||
interface GreetSignature { | ||
Args: { target: string }; | ||
} | ||
|
||
export const InferredGreet: TemplateComponent<GreetSignature> = hbs`Hello, {{@target}}`; | ||
|
||
export const ExplicitGreet = hbs<GreetSignature>`Hello, {{@target}}`; | ||
|
||
expectTypeOf<SignatureOf<typeof ExplicitGreet>>().toEqualTypeOf<GreetSignature>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { expectTypeOf } from 'expect-type'; | ||
import { helper, Helper, fn, FnHelper } from '@glimmerx/helper'; | ||
|
||
declare module '@glimmerx/helper/dist/commonjs/src/helper' { | ||
// For the purposes of testing, make the instance type dependent on the `S` parameter, | ||
// even if in practice the variance wouldn't be quite right. | ||
export interface HelperInstance<S> { | ||
signature: S; | ||
} | ||
} | ||
|
||
type SignatureOf<T> = T extends Helper<infer S> ? S : unknown; | ||
|
||
expectTypeOf(fn).toEqualTypeOf<FnHelper>(); | ||
|
||
const myHelper = helper((_: [], { arg }: { arg: string }) => arg); | ||
|
||
expectTypeOf<SignatureOf<typeof myHelper>>().toEqualTypeOf<{ | ||
Args: { | ||
Positional: []; | ||
Named: { arg: string }; | ||
}; | ||
Return: string; | ||
}>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { expectTypeOf } from 'expect-type'; | ||
import { on, OnModifier } from '@glimmerx/modifier'; | ||
|
||
expectTypeOf(on).toEqualTypeOf<OnModifier>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../tsconfig.json", | ||
"exclude": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters