From de793bc6eda68a2471f1d97c41518e55cd9a4b3c Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 8 Jul 2026 12:57:18 +0100 Subject: [PATCH] DEV: add typescript support for core, themes and plugins (#41478) We've been using basic type-checking via JSDoc for some time. This commit allows us to author proper `.ts`/`.gts` files, and use the full typescript syntax. Initially, only d-button and a single chat file are migrated, as proof of functionality. In future, we may migrate more files, and consider making our tsconfig more strict. --- .prettierignore | 1 + bin/lint | 6 +- .../docs/03-code-internals/26-types.md | 19 +- eslint.config.mjs | 6 +- .../asset-processor/asset-processor-rollup.js | 9 +- frontend/asset-processor/package.json | 1 + .../rollup-plugins/discourse-file-search.js | 2 +- .../rollup-plugins/discourse-gjs.js | 2 +- .../asset-processor/rollup-virtual-imports.js | 14 +- frontend/discourse-i18n/src/index.js | 2 +- frontend/discourse/admin/compat-modules.js | 4 +- .../app/ui-kit/{d-button.gjs => d-button.gts} | 151 +++++----- frontend/discourse/babel.config.cjs | 12 + .../discourse/dialog-holder/compat-modules.js | 4 +- .../discourse/float-kit/compat-modules.js | 4 +- .../lib/wrap-test-modules-plugin.mjs | 2 +- frontend/discourse/package.json | 1 + .../discourse/select-kit/compat-modules.js | 4 +- .../tests/helpers/create-pretender.js | 9 +- frontend/discourse/tests/loader-shims.js | 11 +- .../discourse/tests/test-boot-ember-cli.js | 2 +- .../discourse/truth-helpers/compat-modules.js | 4 +- lefthook.yml | 12 +- lib/asset_processor.rb | 2 +- lib/plugin/instance.rb | 4 +- lib/plugin/js_manager.rb | 9 +- lib/tasks/themes.rake | 4 +- package.json | 6 +- ...ibility.js => check-message-visibility.ts} | 10 +- pnpm-lock.yaml | 282 +++++++++++++++--- spec/system/theme_typescript_spec.rb | 43 +++ 31 files changed, 477 insertions(+), 165 deletions(-) rename frontend/discourse/app/ui-kit/{d-button.gjs => d-button.gts} (74%) rename plugins/chat/assets/javascripts/discourse/lib/{check-message-visibility.js => check-message-visibility.ts} (70%) create mode 100644 spec/system/theme_typescript_spec.rb diff --git a/.prettierignore b/.prettierignore index ac481a74096..ca079d4c43b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -26,3 +26,4 @@ tmp/ **/*.json !**/tsconfig.json **/*.md +**/*.d.ts diff --git a/bin/lint b/bin/lint index fab35810ae9..277b0fd4f42 100755 --- a/bin/lint +++ b/bin/lint @@ -12,8 +12,8 @@ PROJECT_ROOT = File.expand_path("..", __dir__) # live outside the core repo (e.g. plugins/*) where lefthook is not available. class ExternalLinter RUBY_EXTENSIONS = %w[rb rake thor].freeze - PRETTIER_EXTENSIONS = %w[css scss js gjs cjs mjs].freeze - ESLINT_EXTENSIONS = %w[js gjs].freeze + PRETTIER_EXTENSIONS = %w[css scss js gjs cjs mjs ts gts mts cts].freeze + ESLINT_EXTENSIONS = %w[js gjs ts gts mts cts].freeze STYLELINT_EXTENSIONS = %w[scss].freeze JS_EXTENSIONS = (PRETTIER_EXTENSIONS + ESLINT_EXTENSIONS + STYLELINT_EXTENSIONS).uniq.freeze @@ -239,7 +239,7 @@ class LefthookLinter end # Check if file extension is lintable - lintable_extensions = %w[rb rake js gjs hbs scss css yml yaml thor] + lintable_extensions = %w[rb rake js gjs ts gts mts cts hbs scss css yml yaml thor] lintable_extensions.include?(ext) end diff --git a/docs/developer-guides/docs/03-code-internals/26-types.md b/docs/developer-guides/docs/03-code-internals/26-types.md index d79213840ae..c3c241f3348 100644 --- a/docs/developer-guides/docs/03-code-internals/26-types.md +++ b/docs/developer-guides/docs/03-code-internals/26-types.md @@ -8,6 +8,10 @@ Discourse ships type information for its JavaScript code. This can provide inlin Much of this will be automatically consumed by IDEs with TypeScript/JavaScript support. But for functionality in `.gjs` files, you'll need some specific configuration and/or IDE plugins. +## Writing TypeScript + +Core, themes and plugins can be authored directly in TypeScript. Use a `.ts` extension for plain modules, or `.gts` for Glimmer components with a `