discourse-writing-typescript

Write and convert strict-grade TypeScript for Discourse components, modifiers, and services.

47.8k|9.0k|Updated Jan 12, 2013
One-click install
npx skills add https://github.com/discourse/discourse --skill discourse-writing-typescript
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: discourse-writing-typescript
Source: https://github.com/discourse/discourse/tree/main/.skills/discourse-writing-typescript
Command: npx skills add https://github.com/discourse/discourse --skill discourse-writing-typescript

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve?

Discourse's global tsconfig is deliberately not strict, so type-checking alone cannot guarantee correct TypeScript in core, plugins, and themes. This Skill encodes the strict-grade authoring bar, the faithful-port rules for converting .js/.gjs files to .ts/.gts, and the runtime pitfalls (like stale extensioned imports) that ember-tsc never catches.

Core Features & Use Cases

  • Component and modifier patterns: Signature interfaces for .gts components (Args, Element, Blocks), template-only components via TOC, ember-modifier classes, and typed @service declare injection with Service-suffixed bindings.
  • Faithful JS-to-TS conversion: A catalogue of forbidden transformations that pass lint:types but change runtime behavior, plus rename mechanics under squash-merge and a per-file conversion-completeness checklist.
  • Compile-time type tests: Guidance for expect-type tests in frontend/discourse/type-tests, including the rule to split @glint-expect-error negatives into separate files.
  • Use Case: When converting a .gjs component to .gts, apply the faithful-port rules to keep every guard and fallback intact, type the Signature against all real call sites, grep for stale .gjs imports, and verify with bin/lint, pnpm lint:types, and bin/qunit.

Quick Start

Ask the AI to convert a specific Discourse .gjs component to .gts with a fully typed Signature and typed service injections, then run the lint, type-check, and test verification steps.

Frequently Asked Questions about discourse-writing-typescript

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I convert a .gjs component to .gts in Discourse?

Perform a types-only port: add a Signature interface and type annotations without changing any runtime code, guards, or fallbacks. Rename with a single git mv commit, grep for stale extensioned imports, then verify with bin/lint, pnpm lint:types, and bin/qunit.

How do I type an injected Ember service in TypeScript?

Use @service declare with an imported type, such as import type TooltipService from the service module followed by @service declare tooltip: TooltipService. A bare @service leaves the property implicitly any, which violates the no-any bar.

Why does pnpm lint:types pass but tests fail after a rename?

Consumers importing the old explicit extension like x.gjs are not type-checked, so ember-tsc misses the stale specifier and the bundle fails at runtime with a module resolution error. Grep for extensioned imports and change them to extensionless.

Can I tighten the Discourse tsconfig to enable strict mode?

No. The global tsconfig is deliberately loose and tightening it is a separate repo-wide effort. Author files as if strict were on: no any, no @ts-ignore, and precise Signatures, but never change the tsconfig in a feature PR.

When should I defer converting a file to TypeScript?

Defer when the file drags in several untyped internals needing ComponentLike casts, has dozens of consumers where tightening leaks type errors, or is owned by another area like FloatKit or FormKit. Give such files their own coordinated PR.