Skip to content

Commit

Permalink
Merge pull request #20410 from NullVoxPopuli/add-ember-template-compi…
Browse files Browse the repository at this point in the history
…lation

[BUGFIX types] Add missing type declarations in the preview types for @ember/template-compilation
  • Loading branch information
chriskrycho authored Mar 22, 2023
2 parents 15e3e07 + 8d18b07 commit 2217669
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 5 deletions.
31 changes: 31 additions & 0 deletions type-tests/@ember/template-compilation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { precompileTemplate } from '@ember/template-compilation';
import { setComponentTemplate } from '@ember/component';
import templateOnly from '@ember/component/template-only';

import { expectTypeOf } from 'expect-type';

// Valid usages
precompileTemplate(`Hello World`, { moduleName: 'foo' });
precompileTemplate(`Hello World`, { moduleName: 'foo', strictMode: false });
precompileTemplate(`Hello World`, { strictMode: false });
precompileTemplate(`Hello World`, { strictMode: true, scope: () => ({}) });
precompileTemplate(`Hello World`, { strictMode: true, scope: () => ({ setComponentTemplate }) });
precompileTemplate(`Hello World`, { strictMode: true, moduleName: 'hello', scope: () => ({}) });

// Integration, since this is the primary use case for precompileTemplate
expectTypeOf(setComponentTemplate(precompileTemplate(`Hello World`), templateOnly())).toBeObject();

// @ts-expect-error scope is required when strictMode is true
precompileTemplate(`Hello World`, { strictMode: true });

// @ts-expect-error scope must be a function
precompileTemplate(`Hello World`, { strictMode: true, scope: {} });

// @ts-expect-error scope must return an object
precompileTemplate(`Hello World`, { strictMode: true, scope: () => {} });

// @ts-expect-error scope must return an object and arrays are not the kind of object we want
precompileTemplate(`Hello World`, { strictMode: true, scope: () => [] });

// @ts-expect-error scope has no purpose when strictMode is false
precompileTemplate(`Hello World`, { strictMode: false, scope: () => ({}) });
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ declare module '@ember/component/-private/glimmer-interfaces' {
createComponent(factory: object, args: Arguments): ComponentStateBucket;
getContext(instance: ComponentStateBucket): unknown;
}

export interface TemplateFactory {
__htmlbars_inline_precompile_template_factory: any;
}
}
10 changes: 5 additions & 5 deletions types/preview/@ember/component/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
declare module '@ember/component' {
import CoreView from '@ember/component/-private/core-view';
import ClassNamesSupport from '@ember/component/-private/class-names-support';
import { TemplateFactory } from '@ember/component/-private/glimmer-interfaces';
import ViewMixin from '@ember/component/-private/view-mixin';
import { ComponentManager, Capabilities } from '@ember/component/-private/glimmer-interfaces';
import { Opaque } from 'ember/-private/type-utils';

// Re-export these types so people can use them!
export { ComponentManager, Capabilities };

interface TemplateFactory {
__htmlbars_inline_precompile_template_factory: any;
}

// The generic here is for a *signature: a way to hang information for tools
// like Glint which can provide typey checking for component templates using
// information supplied via this generic. While it may appear useless on this
Expand Down Expand Up @@ -136,7 +133,10 @@ declare module '@ember/component' {
updateHook: boolean;
}

export function capabilities<Version extends keyof ComponentCapabilitiesVersions>(managerAPI: Version, options?: ComponentCapabilitiesVersions[Version]): ComponentCapabilities;
export function capabilities<Version extends keyof ComponentCapabilitiesVersions>(
managerAPI: Version,
options?: ComponentCapabilitiesVersions[Version]
): ComponentCapabilities;

// In normal TypeScript, these built-in components are essentially opaque tokens
// that just need to be importable. Declaring them with unique interfaces
Expand Down
28 changes: 28 additions & 0 deletions types/preview/@ember/template-compilation/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* References:
* - https://github.com/emberjs/rfcs/pull/496
* - https://github.com/emberjs/rfcs/pull/779
*/
declare module '@ember/template-compilation' {
import type { TemplateFactory } from '@ember/component/-private/glimmer-interfaces';

interface MaybeModuleName {
moduleName?: string;
}

interface LooseMode extends MaybeModuleName {
strictMode?: false;
}

interface StrictMode extends MaybeModuleName {
strictMode: true;
scope: () => Record<string, unknown>;
}

type PrecompileTemplateOptions = LooseMode | StrictMode;

export function precompileTemplate(
template: string,
options?: PrecompileTemplateOptions
): TemplateFactory;
}
2 changes: 2 additions & 0 deletions types/preview/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ import './@ember/service';
import './@ember/template';
import './@ember/template/-private/handlebars';

import './@ember/template-compilation';

import './@ember/test';
import './@ember/test/adapter';

Expand Down

0 comments on commit 2217669

Please sign in to comment.