diff --git a/packages/typescript-plugin/src/typescript-server-plugin.ts b/packages/typescript-plugin/src/typescript-server-plugin.ts index 2831ebfa..140d9d9f 100644 --- a/packages/typescript-plugin/src/typescript-server-plugin.ts +++ b/packages/typescript-plugin/src/typescript-server-plugin.ts @@ -10,7 +10,9 @@ const { const plugin = createAsyncLanguageServicePlugin( ['.gts', '.gjs', '.hbs'], (fileName: string) => { - if (fileName.endsWith('.gts')) { + if (fileName.endsWith('.hbs')) { + return 3 satisfies ts.ScriptKind.TS; + } else if (fileName.endsWith('.gts')) { return 3 satisfies ts.ScriptKind.TS; } else if (fileName.endsWith('.gjs')) { return 1 satisfies ts.ScriptKind.JS; diff --git a/packages/vscode/package.json b/packages/vscode/package.json index 446a2d8d..4f3b1e85 100644 --- a/packages/vscode/package.json +++ b/packages/vscode/package.json @@ -162,6 +162,7 @@ { "name": "@glint/typescript-plugin", "enableForWorkspaceTypeScriptVersions": true, + "configNamespace": "typescript", "languages": [ "glimmer-ts", "glimmer-js" diff --git a/test-packages/ts-plugin-test-app/package.json b/test-packages/ts-plugin-test-app/package.json index be7b4714..7c39b307 100644 --- a/test-packages/ts-plugin-test-app/package.json +++ b/test-packages/ts-plugin-test-app/package.json @@ -10,6 +10,8 @@ "description": "", "devDependencies": { "typescript": "*", + "@glint/core": "*", + "@glint/environment-ember-loose": "*", "@glint/typescript-plugin": "*" } } diff --git a/test-packages/ts-plugin-test-app/src/ember-component.hbs b/test-packages/ts-plugin-test-app/src/ember-component.hbs index 7dd4f4d0..f622e109 100644 --- a/test-packages/ts-plugin-test-app/src/ember-component.hbs +++ b/test-packages/ts-plugin-test-app/src/ember-component.hbs @@ -1,6 +1,28 @@ -{{! TODO: this isn't working yet }} -{{foo}} +
+ {{this.required}} + {{this.optional}} + {{this.hasDefault}} -
- {{this.bar}} -
\ No newline at end of file + {{@required}} + {{@optional}} + {{@hasDefault}} + + {{!-- + This pair of checks needs to work in this app, which uses DT types, and the + preview/stable types app which does *not*. + --}} + {{get this "required"}} + + {{! @glint-expect-error: non-existent property }} + {{get this "unrelated"}} +
+ +{{#if this.showFunctionHelpers}} + {{! @glint-expect-error: missing arg }} + {{this.isLongString}} + + {{! @glint-expect-error: wrong arg type }} + {{this.isLongString 123}} + + {{this.isLongString 'hi'}} +{{/if}} \ No newline at end of file diff --git a/test-packages/ts-plugin-test-app/src/ember-component.ts b/test-packages/ts-plugin-test-app/src/ember-component.ts index 969e2955..6513e079 100644 --- a/test-packages/ts-plugin-test-app/src/ember-component.ts +++ b/test-packages/ts-plugin-test-app/src/ember-component.ts @@ -1,3 +1,38 @@ -export default class EmberComponent { - foo = 123; +/* eslint-disable ember/no-classic-components, ember/require-tagless-components */ +import Component from '@ember/component'; + +export interface EmberComponentArgs { + required: string; + hasDefault?: string; + optional?: number; +} + +export interface EmberComponentSignature { + Element: HTMLDivElement; + Args: EmberComponentArgs; +} + +export default interface EmberComponent extends EmberComponentArgs {} +export default class EmberComponent extends Component { + public hasDefault = 'defaultValue'; + public showFunctionHelpers = false; + + public isLongString(value: string): boolean { + return value.length > 5; + } + + public checkTypes(): unknown { + const required: string = this.required; + const hasDefault: string = this.hasDefault; + const optional: number | undefined = this.optional; + + return { required, hasDefault, optional }; + } +} + +declare module '@glint/environment-ember-loose/registry' { + export default interface Registry { + EmberComponent: typeof EmberComponent; + 'ember-component': typeof EmberComponent; + } } diff --git a/test-packages/ts-plugin-test-app/src/js-component.hbs b/test-packages/ts-plugin-test-app/src/js-component.hbs new file mode 100644 index 00000000..324e005b --- /dev/null +++ b/test-packages/ts-plugin-test-app/src/js-component.hbs @@ -0,0 +1 @@ +{{this.message}} \ No newline at end of file diff --git a/test-packages/ts-plugin-test-app/src/js-component.js b/test-packages/ts-plugin-test-app/src/js-component.js new file mode 100644 index 00000000..4cdfaaef --- /dev/null +++ b/test-packages/ts-plugin-test-app/src/js-component.js @@ -0,0 +1,5 @@ +import Component from '@glimmer/component'; + +export default class MyComponent extends Component { + message = 'hi'; +} diff --git a/test-packages/ts-plugin-test-app/src/wrapper-component.hbs b/test-packages/ts-plugin-test-app/src/wrapper-component.hbs new file mode 100644 index 00000000..8db3d908 --- /dev/null +++ b/test-packages/ts-plugin-test-app/src/wrapper-component.hbs @@ -0,0 +1 @@ +{{yield (hash InnerComponent=(component "ember-component" required=@value))}} diff --git a/test-packages/ts-plugin-test-app/src/wrapper-component.ts b/test-packages/ts-plugin-test-app/src/wrapper-component.ts new file mode 100644 index 00000000..c107f285 --- /dev/null +++ b/test-packages/ts-plugin-test-app/src/wrapper-component.ts @@ -0,0 +1,28 @@ +/* eslint-disable ember/no-classic-components, ember/require-tagless-components */ +import { ComponentLike, WithBoundArgs } from '@glint/template'; +import Component from '@ember/component'; +import EmberComponent from './ember-component'; + +interface WrapperComponentSignature { + Element: HTMLDivElement; + Args: { + value: string; + }; + Blocks: { + default: [ + { + InnerComponent: WithBoundArgs; + MaybeComponent?: ComponentLike<{ Args: { key: string } }>; + stringValue?: string; + }, + ]; + }; +} + +export default class WrapperComponent extends Component {} + +declare module '@glint/environment-ember-loose/registry' { + export default interface Registry { + WrapperComponent: typeof WrapperComponent; + } +}