From 51714e032d30a4d860b08025af4ada770c9f913c Mon Sep 17 00:00:00 2001 From: Matt Davidson Date: Thu, 7 May 2026 14:06:13 -0700 Subject: [PATCH] feat: bootstrap TypeScript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sets up the toolchain for an incremental TS migration. No source files converted in this PR — those follow leaf-first. Adds: - tsconfig.json with the same strictness as our other repos: strict, noFallthroughCasesInSwitch, noImplicitOverride, noUncheckedIndexedAccess, noUnusedLocals, noUnusedParameters. Also Next.js conventions (jsx: preserve, plugins: [next], paths, isolatedModules, incremental). allowJs is on so tsc can partially check the still-JS files during migration; Next auto-adds it on build either way. - typescript, @types/node, @types/react, @types/react-dom devDeps. - A `typecheck` script (`tsc --noEmit`) and a step in ci.yml. - next-env.d.ts (Next-generated, don't edit). - *.tsbuildinfo to .gitignore. - ignorePatterns in .oxlintrc.json so oxlint skips next-env.d.ts (Next's triple-slash references conflict with the lint rule). Verified: lint, typecheck, format:check, and build all pass. --- .github/workflows/ci.yml | 2 + .gitignore | 1 + .oxlintrc.json | 3 +- next-env.d.ts | 6 +++ package-lock.json | 107 ++++++++++++++++++++++++++++++++++++++- package.json | 9 +++- tsconfig.json | 33 ++++++++++++ 7 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 next-env.d.ts create mode 100644 tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0fa957..e4cbda0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,4 +26,6 @@ jobs: - run: npm run format:check + - run: npm run typecheck + - run: npm run build diff --git a/.gitignore b/.gitignore index 0658cf9..d0df3d0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .next .vercel node_modules +*.tsbuildinfo diff --git a/.oxlintrc.json b/.oxlintrc.json index bdd0ada..ead5ddc 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -7,5 +7,6 @@ "rules": { "no-console": "warn", "no-unused-vars": "warn" - } + }, + "ignorePatterns": ["next-env.d.ts", ".next/", "node_modules/"] } diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..254b73c --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. diff --git a/package-lock.json b/package-lock.json index 2e0a074..39f28ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,11 +24,15 @@ "@tailwindcss/forms": "^0.5.6", "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.9", + "@types/node": "^25.6.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "autoprefixer": "^10.4.15", "oxfmt": "^0.48.0", "oxlint": "^1.63.0", "postcss": "^8.5.10", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.3", + "typescript": "^6.0.3" }, "engines": { "node": "24.x" @@ -1731,6 +1735,36 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@types/node": { + "version": "25.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.1.tgz", + "integrity": "sha512-coJCN8O1q4AGyyqCAUSP06P+SrMTu18BkEj3NVAK07q6QUneD2wzj3CLv9+yP+BMeZQlMvneXqqvDe3w+xcq7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, "node_modules/@workos-inc/node": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/@workos-inc/node/-/node-8.13.0.tgz", @@ -1962,6 +1996,13 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3149,6 +3190,27 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "dev": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -4024,6 +4086,31 @@ "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.14.0.tgz", "integrity": "sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==" }, + "@types/node": { + "version": "25.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.1.tgz", + "integrity": "sha512-coJCN8O1q4AGyyqCAUSP06P+SrMTu18BkEj3NVAK07q6QUneD2wzj3CLv9+yP+BMeZQlMvneXqqvDe3w+xcq7g==", + "dev": true, + "requires": { + "undici-types": "~7.19.0" + } + }, + "@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "requires": { + "csstype": "^3.2.2" + } + }, + "@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "requires": {} + }, "@workos-inc/node": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/@workos-inc/node/-/node-8.13.0.tgz", @@ -4165,6 +4252,12 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true + }, "detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -4953,6 +5046,18 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true + }, + "undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/package.json b/package.json index be2cf53..8662e77 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "lint": "oxlint", "lint:fix": "oxlint --fix", "format": "oxfmt", - "format:check": "oxfmt --check" + "format:check": "oxfmt --check", + "typecheck": "tsc --noEmit" }, "dependencies": { "@datadog/browser-rum": "^7.0.0", @@ -26,11 +27,15 @@ "@tailwindcss/forms": "^0.5.6", "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.9", + "@types/node": "^25.6.1", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", "autoprefixer": "^10.4.15", "oxfmt": "^0.48.0", "oxlint": "^1.63.0", "postcss": "^8.5.10", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.3.3", + "typescript": "^6.0.3" }, "engines": { "node": "24.x" diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6e91715 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["dom", "dom.iterable", "esnext"], + "skipLibCheck": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + }, + "allowJs": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}