{"_id":"@7ka/tsconfig","name":"@7ka/tsconfig","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@7ka/tsconfig","version":"0.1.0","description":"Strict TypeScript configs for Vite, React, and Next.js projects","publishConfig":{"access":"public"},"license":"MIT","keywords":["typescript","tsconfig","react","vite","nextjs","strict"],"repository":{"type":"git","url":"git+https://github.com/7ka-dev/tooling.git","directory":"packages/tsconfig"},"homepage":"https://github.com/7ka-dev/tooling/tree/master/packages/tsconfig","_id":"@7ka/tsconfig@0.1.0","gitHead":"bef7767c7929a9d3950702c2646bf0c448e06c7b","bugs":{"url":"https://github.com/7ka-dev/tooling/issues"},"_nodeVersion":"24.11.1","_npmVersion":"10.8.3","dist":{"integrity":"sha512-BEdSFyhUVHIEI6pvu2G5iF3iYN+rg1YrHQSqmVhTX2ozRK97SzYmPUZc9aNDp+cgfef7imb+7o0kXdo3wP08yA==","shasum":"baca0447bceaa3613a0bc1b662c46d3503e38394","tarball":"https://registry.npmjs.org/@7ka/tsconfig/-/tsconfig-0.1.0.tgz","fileCount":5,"unpackedSize":8947,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC5pywy6SCSY40tqaUYqKcXouBWrA+hJaKJxIjJXtWuZAIgeY3z8FjCQj0/yIXsA4MxOa99K/bnOsGgWVPIpWj2JOU="}]},"_npmUser":{"name":"npm7ka","email":"npm@7ka.dev"},"directories":{},"maintainers":[{"name":"npm7ka","email":"npm@7ka.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tsconfig_0.1.0_1773211260040_0.1720663578439312"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T06:40:59.941Z","0.1.0":"2026-03-11T06:41:00.170Z","modified":"2026-03-11T06:41:00.415Z"},"maintainers":[{"name":"npm7ka","email":"npm@7ka.dev"}],"description":"Strict TypeScript configs for Vite, React, and Next.js projects","homepage":"https://github.com/7ka-dev/tooling/tree/master/packages/tsconfig","keywords":["typescript","tsconfig","react","vite","nextjs","strict"],"repository":{"type":"git","url":"git+https://github.com/7ka-dev/tooling.git","directory":"packages/tsconfig"},"bugs":{"url":"https://github.com/7ka-dev/tooling/issues"},"license":"MIT","readme":"# @7ka/tsconfig\n\nShared TypeScript configs for 7ka collective projects.\n\n---\n\n## Install\n\n```bash\nnpm install -D @7ka/tsconfig\n```\n\n---\n\n## Usage\n\n### React (Vite)\n```json\n// tsconfig.json\n{\n  \"extends\": \"@7ka/tsconfig/react.json\",\n  \"include\": [\"src\"]\n}\n```\n\n### Next.js\n```json\n// tsconfig.json\n{\n  \"extends\": \"@7ka/tsconfig/next.json\",\n  \"include\": [\"src\", \"next.config.ts\"]\n}\n```\n\n### Base (no DOM — shared logic, utilities)\n```json\n{\n  \"extends\": \"@7ka/tsconfig/base.json\",\n  \"include\": [\"src\"]\n}\n```\n\n---\n\n## What's enforced\n\n### Compiler\n\n| Option | Value | Why |\n|---|---|---|\n| `target` | `ES2022` | Modern JS, no over-polyfilling |\n| `module` | `ESNext` | Native ESM |\n| `moduleResolution` | `bundler` | Matches Vite resolution, no `.js` extensions required |\n| `jsx` | `react-jsx` (react) / `preserve` (next) | Correct per framework |\n\n### Strict flags\n\n| Flag | Why |\n|---|---|\n| `strict` | Master switch — enables all core strict checks |\n| `noUncheckedIndexedAccess` | Array index access returns `T \\| undefined`, not just `T` |\n| `noImplicitReturns` | All code paths must explicitly return |\n| `noFallthroughCasesInSwitch` | Switch cases must break, return, or throw |\n| `exactOptionalPropertyTypes` | Optional `?` means absent — not `undefined` |\n| `noPropertyAccessFromIndexSignature` | Dynamic key access must use bracket notation |\n| `noImplicitOverride` | Class overrides must be marked with `override` keyword |\n| `forceConsistentCasingInFileNames` | Prevents casing bugs between macOS and Linux CI |\n\n---\n\n## Rule Details\n\n### `strict`\n\nThis is not a single rule — it's a bundle. Enabling `strict: true` turns on all of the following at once: `strictNullChecks`, `strictFunctionTypes`, `strictBindCallApply`, `strictPropertyInitialization`, `noImplicitAny`, `noImplicitThis`, and `alwaysStrict`.\n\nThe most important of these is `strictNullChecks` — without it, `null` and `undefined` are silently assignable to every type, which means TypeScript won't tell you when something might not exist. This is the single biggest source of runtime crashes that TypeScript is supposed to prevent. `strict` mode closes that gap.\n\n---\n\n### `noUncheckedIndexedAccess`\n\nBy default TypeScript assumes that if you access an array by index, you get a value of the array's element type. It does not account for the possibility that the array is empty or the index is out of bounds. This flag adds `| undefined` to every index access, forcing you to handle the case where nothing is there.\n\nThis matters most in React when mapping over API responses — you can't always guarantee the array has content.\n\n```ts\nconst users: User[] = getUsers()\n\n// without flag — TypeScript trusts you, runtime crash if empty\nconst first = users[0]\nconsole.warn(first.name) // TypeError if array is empty\n\n// with flag — TypeScript is honest\nconst first = users[0] // typed as User | undefined\nif (!first) return\nconsole.warn(first.name) // safe\n```\n\n---\n\n### `noImplicitReturns`\n\nWhen a function is supposed to return a value, TypeScript will error if any code path exits without an explicit return statement. Without this flag, a missing return silently produces `undefined` — which then propagates through your app as a hard-to-trace bug.\n\n```ts\n// bad — second path returns undefined implicitly, TypeScript silent\nfunction getLabel(status: string): string {\n  if (status === 'active') return 'Active'\n  // forgot this path — returns undefined at runtime\n}\n\n// good — all paths accounted for\nfunction getLabel(status: string): string {\n  if (status === 'active') return 'Active'\n  return 'Unknown'\n}\n```\n\n---\n\n### `noFallthroughCasesInSwitch`\n\nIn a `switch` statement, if a `case` block doesn't end with `break`, `return`, or `throw`, execution falls through to the next case. This is almost never intentional and causes logic bugs that are difficult to spot during review.\n\n```ts\n// bad — 'admin' falls through to 'user', both branches execute\nswitch (role) {\n  case 'admin':\n    grantAdminAccess()\n  case 'user':\n    showDashboard()\n    break\n}\n\n// good — each case is isolated\nswitch (role) {\n  case 'admin':\n    grantAdminAccess()\n    break\n  case 'user':\n    showDashboard()\n    break\n}\n```\n\n---\n\n### `exactOptionalPropertyTypes`\n\nWhen you mark an interface property as optional with `?`, TypeScript normally treats it as \"this property may be absent or explicitly set to `undefined`.\" This flag tightens that — optional means the property is simply absent. Setting it to `undefined` explicitly becomes a type error.\n\nThis distinction matters when working with APIs or databases that treat a missing key differently from a key with a `null`/`undefined` value — which is common in REST and GraphQL responses.\n\n```ts\ninterface Config {\n  timeout?: number\n}\n\n// bad — property present but undefined, may behave differently at runtime\nconst config: Config = { timeout: undefined }\n\n// good — property is simply not there\nconst config: Config = {}\n```\n\n---\n\n### `noPropertyAccessFromIndexSignature`\n\nWhen an interface has an index signature (a dynamic `[key: string]` definition), TypeScript normally lets you access those dynamic keys with dot notation — the same as known, static properties. This flag forces bracket notation for dynamic keys, making it visually obvious at the call site that you're doing a dynamic lookup that may or may not exist.\n\n```ts\ninterface Env {\n  [key: string]: string\n  NODE_ENV: string   // known, static property\n}\n\n// bad — dot notation hides the fact this is a dynamic lookup\nconst val = env.SOME_KEY\n\n// good — bracket notation signals \"this might not be here\"\nconst val = env['SOME_KEY']\n\n// still fine — known property keeps dot notation\nconst mode = env.NODE_ENV\n```\n\n---\n\n### `noImplicitOverride`\n\nWhen a child class defines a method with the same name as a method in its parent class, it silently overrides it. This is fine when intentional but dangerous when it happens by accident — or when the parent method is later renamed or removed, leaving the child with an orphaned method that nobody notices.\n\nThis flag requires you to explicitly mark overriding methods with the `override` keyword. If the parent method is renamed or removed, TypeScript will error on the `override` annotation immediately.\n\n```ts\nclass Base {\n  render(): string {\n    return 'base'\n  }\n}\n\n// bad — silent override, nothing catches it if Base.render is renamed\nclass Child extends Base {\n  render(): string {\n    return 'child'\n  }\n}\n\n// good — explicit intent, TypeScript errors if parent method disappears\nclass Child extends Base {\n  override render(): string {\n    return 'child'\n  }\n}\n```\n\n---\n\n### `forceConsistentCasingInFileNames`\n\nmacOS and Windows file systems are case-insensitive — `UserCard.tsx` and `usercard.tsx` resolve to the same file. Linux (where CI runs) is case-sensitive — they are different files. This means code that works locally on a Mac can silently fail in CI or production.\n\nThis flag makes TypeScript error when an import's casing doesn't match the actual filename on disk, catching the mismatch before it reaches CI.\n\n```ts\n// file on disk: UserCard.tsx\n\n// bad — works on Mac, breaks on Linux CI\nimport { UserCard } from './usercard'\n\n// good\nimport { UserCard } from './UserCard'\n```","readmeFilename":"README.md","_rev":"1-d14b8b5a3900e2d5100ad444160ae014"}