Advanced TypeScript for Harness Builders
0e. Type Narrowing (Runtime)
TypeScript's killer feature: it tracks runtime checks and narrows types automatically.
TypeScript tracks runtime checks and narrows types automatically. This is its killer feature.
typeof checks:
File: packages/ai/src/env-api-keys.ts L14
if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
// Inside here, TypeScript knows `process` exists
}
instanceof checks:
File: packages/mom/src/log.ts L167
err instanceof Error ? err.message : String(err);
After instanceof Error, TypeScript knows err has .message.
Truthiness narrowing:
File: packages/mom/src/sandbox.ts L36-38
const result = await execSimple("docker", ["inspect", "-f", "...", config.container]);
if (result.trim() !== "true") {
// TypeScript still knows result is string here
console.error(`Error: Container '${config.container}' is not running.`);
}
Optional chaining (?.) narrows to undefined:
File: packages/ai/src/env-api-keys.ts L14
process.versions?.node || process.versions?.bun;
?. returns undefined if the left side is null/undefined. Combined with ||, this is a safe way to check nested properties.
These are all JavaScript features, but TypeScript is the one that tracks them for type safety. In JS, typeof is just a runtime check. In TS, it also changes what the compiler thinks the type is inside the if block.