Trying another approach here and also hitting issue with type checking specifically.
For my use case I only really need the context I’m trying to add on the API side so I tried to make a global apiContext instead of using Redwood’s conext:
# api/types/global.d.ts
import { getCurrentApiUser } from 'src/lib/auth'
export type CurrentApiUser = Awaited<ReturnType<typeof getCurrentApiUser>>
type ApiContext = {
  currentUser: CurrentApiUser | null
}
declare global {
  const apiContext: ApiContext
}
export {}
# api/tsconfig.json
{
  "compilerOptions": {
    "noEmit": true,
    "allowJs": true,
    "esModuleInterop": true,
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "skipLibCheck": false,
    "baseUrl": "./",
    "rootDirs": [
      "./src",
      "../.redwood/types/mirror/api/src"
    ],
    "paths": {
      "src/*": [
        "./src/*",
        "../.redwood/types/mirror/api/src/*"
      ],
      "types/*": ["./types/*", "../types/*"],
      "@redwoodjs/testing": ["../node_modules/@redwoodjs/testing/api"]
    },
    "typeRoots": [
      "../node_modules/@types",
      "./node_modules/@types"
    ],
    "types": ["jest"],
    "jsx": "react-jsx"
  },
  "include": [
    "src",
    "../.redwood/types/includes/all-*",
    "../.redwood/types/includes/api-*",
    "../types",
    "./types"
  ]
}
With this setup I am able to access apiContext.currentUser as expected and my IDE has the correct typings:

But when I run yarn rw type-check I am again getting errors:
node ➜ /workspace $ yarn rw type-check
✔ Generating the Prisma client...
✔ Generating types
../api/src/lib/auth.ts:76:12 - error TS2552: Cannot find name 'apiContext'. Did you mean 'context'?
76   return !!apiContext.currentUser || false
              ~~~~~~~~~~
  ../node_modules/@redwoodjs/graphql-server/dist/global.api-auto-imports.d.ts:5:11
    5     const context: GlobalContext;
                ~~~~~~~
    'context' is declared here.
../api/src/lib/auth.ts:153:30 - error TS2552: Cannot find name 'apiContext'. Did you mean 'context'?
153       args[stationIdArg] !== apiContext.currentUser.station.id
                                 ~~~~~~~~~~
  ../node_modules/@redwoodjs/graphql-server/dist/global.api-auto-imports.d.ts:5:11
    5     const context: GlobalContext;
                ~~~~~~~
    'context' is declared here.
Found 2 errors in the same file, starting at: ../api/src/lib/auth.ts:76
This seems more like more of a general TS configuration/typing thing.
I also just noticed that the errors are coming from the web side type checking:
node ➜ /workspace/api $ yarn tsc --skipLibCheck    
node ➜ /workspace/api $ cd ../web
node ➜ /workspace/web $ yarn tsc --skipLibCheck 
../api/src/lib/auth.ts:76:12 - error TS2552: Cannot find name 'apiContext'. Did you mean 'context'?
76   return !!apiContext.currentUser || false
              ~~~~~~~~~~
  ../node_modules/@redwoodjs/graphql-server/dist/global.api-auto-imports.d.ts:5:11
    5     const context: GlobalContext;
                ~~~~~~~
    'context' is declared here.
../api/src/lib/auth.ts:153:30 - error TS2552: Cannot find name 'apiContext'. Did you mean 'context'?
153       args[stationIdArg] !== apiContext.currentUser.station.id
                                 ~~~~~~~~~~
  ../node_modules/@redwoodjs/graphql-server/dist/global.api-auto-imports.d.ts:5:11
    5     const context: GlobalContext;
                ~~~~~~~
    'context' is declared here.
Found 2 errors in the same file, starting at: ../api/src/lib/auth.ts:76
The web side config looks like this:
# web/tsconfig.json
{
  "compilerOptions": {
    "noEmit": true,
    "allowJs": true,
    "esModuleInterop": true,
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "baseUrl": "./",
    "skipLibCheck": false,
    "rootDirs": [
      "./src",
      "../.redwood/types/mirror/web/src",
      "../api/src",
      "../.redwood/types/mirror/api/src"
    ],
    "paths": {
      "src/*": [
        "./src/*",
        "../.redwood/types/mirror/web/src/*",
        "../api/src/*",
        "../.redwood/types/mirror/api/src/*"
      ],
      "$api/*": [ "../api/*" ],
      "types/*": ["./types/*", "../types/*"],
      "@redwoodjs/testing": ["../node_modules/@redwoodjs/testing/web"]
    },
    "typeRoots": ["../node_modules/@types", "./node_modules/@types"],
    "types": ["jest", "@testing-library/jest-dom"],
    "jsx": "preserve"
  },
  "include": [
    "src",
    "../.redwood/types/includes/all-*",
    "../.redwood/types/includes/web-*",
    "../types",
    "./types"
  ]
}
So the type-check issue goes away if I add ../api/types to include in web/tsconfig.json, which makes sense.
I also spun up a new project and verified that this configurations are basically stock (plus a few small modifications). So a few related questions:
- Does this fix make sense? I’m not familiar enough with TS config to understand how this change might impact anything else. After doing this type checks pass, the IDE is happy, tests pass (expect for 
requireAuth tests because they don’t account for my new global context, which makes sense), and the application still works as expected. 
- Why does 
web/tsconfig.json include api side content in rootDirs and paths in the first place? I assume there is some reason for this. 
- Why does the initial project 
api/tsconfig.json not have ./types in includes? 
This still feels a little off. I think with the information I got from writing this up I can probably make this work by replacing the GlobalContext (thought extending still does not seem doable).