Using AI Responsibly
Advanced · 18 min read · ▶ live playground · ✦ checkpoint
AI-generated TypeScript can compile and still be wrong. Responsible use means treating generated code as untrusted until you can explain it, check it, and defend it in review.
If your name is on the commit, the code is yours. The assistant can draft, explain, and suggest tests, but it cannot carry your responsibility for behavior, privacy, licensing, provenance, or maintainability.
Compiling is not the same as telling the truth
The compiler checks type contracts. It does not know your pricing policy, access policy, copy rules, or product promise.
This generated helper is well-typed and still wrong:
type Plan =
| { kind: "free"; seats: 1 }
| { kind: "pro"; seats: number }
| { kind: "team"; seats: number };
function monthlyPrice(plan: Plan): number {
if (plan.kind === "free") {
return 0;
}
if (plan.kind === "pro") {
return plan.seats * 20;
}
return plan.seats * 20;
}
console.log("team seats:", monthlyPrice({ kind: "team", seats: 3 }));team seats: 60
That is why AI review needs tests and domain examples, not just typecheck. If generated code touches money, permissions, messaging, data retention, or user-visible decisions, write or update the example that proves the rule.
Scan for escape hatches
Generated TypeScript often gets itself unstuck by weakening the type system. The common red flags are loose values, assertions, and ignored diagnostics.
Review target:
type User = {
id: string;
email: string;
isAdmin: boolean;
};
const rawUser: any = {
id: 42,
email: "not-an-email",
admin: true,
};
const user = rawUser as User;
// @ts-ignore
const adminFlag: boolean = user.admin;
console.log(user.isAdmin === true ? "admin" : "not admin");not admin
This code has three separate review problems:
rawUser: anyturns off the checker at the boundary.rawUser as Userdeclares trust without proving the runtime shape.- The ignore comment hides that
adminis not part of the assertedUsertype.
The output is also suspicious. The raw object has admin: true, but the program reads isAdmin, so it prints not admin. The type layer was silenced before it could help.
Good generated TypeScript should make evidence visible:
- Use
unknownfor outside data until a parser, schema, predicate, or assertion function checks it. - Keep assertions narrow and local to a proof that just ran.
- Prefer discriminated unions,
Result<T, E>, and explicit domain types over broad bags of properties. - Treat every ignore comment as a review question: what exact diagnostic was hidden, and why is hiding it safer than fixing it?
Sometimes an assertion is honest. Section 13 used brands and assertion functions after validation. The difference is evidence. A contained assertion after a parser is a receipt for a check that ran. A generated assertion used to make red squiggles disappear is a costume.
Use the explain-it-back rule
The professional line is simple: commit only code you can explain.
Use the explain-it-back rule before accepting generated work:
What changed?
What type contract does the code rely on?
What runtime rule did the compiler not prove?
Which tests or examples cover that rule?
Did the assistant add loose types, assertions, ignore comments, dependencies, files, commands, or network access?
Can I explain every changed line to a teammate in two minutes?If the last answer is no, pause. Ask the assistant for an explanation, reduce the change, or rewrite the section yourself. "It compiles" is useful evidence, not permission to stop thinking.
This rule also protects your skill. Over-reliance means using AI so much that your own reading, debugging, testing, and design muscles weaken. Keep deliberate reps in your workflow:
- Write the first version yourself sometimes, then ask AI to review it.
- Debug one theory yourself before asking for hints.
- Write at least one test yourself before asking for more cases.
- Read generated code line by line before running it.
- Turn off suggestions when you need quiet practice with a new concept.
AI can be a training partner. It should not do every rep.
Protect privacy, secrets, and systems
Do not paste secrets, private customer data, unreleased company code, production logs, or internal documents into AI tools unless your organization explicitly approves that workflow. Even then, share the smallest useful context.
A secret is a value that grants access or must stay private: an API key, password, token, private key, signing secret, database URL, or session cookie. Real secrets belong in approved environment or secret storage, not in prompts, source code, screenshots, generated tests, or debug logs.
Give AI-generated code a security pass when it touches:
- Environment variables or configuration files.
- File reads, writes, deletes, uploads, or downloads.
- Shell commands or package installation.
- Network calls, webhooks, background jobs, or queues.
- Authentication, authorization, logging, analytics, or payment data.
None of those are automatically bad. They are areas where the cost of a plausible mistake is higher. Ask what data leaves the machine, what account pays for it, what permission it uses, and what evidence proves it is safe.
Track license and provenance basics
Licensing is the set of permissions and limits attached to code, documentation, data, or other creative work. Provenance is where a piece of code, text, data, or design came from. This is not legal advice. It is a developer habit for team work.
Safe defaults:
- Follow your employer, school, client, or open-source project policy.
- Do not ask AI to copy code from a specific paid course, private repository, book, or proprietary product.
- Avoid pasting third-party code into prompts unless the license and project rules allow it.
- Keep generated output small enough to review and rewrite.
- Record sources, licenses, or attribution when your project requires them.
- Ask for an original implementation from requirements, not a clone of a named source.
AI can help you notice a risk, but it cannot approve the risk for your project. When policy matters, the responsible answer is to follow the policy and ask the appropriate human reviewer.
Keep the review boring
A good AI-assisted TypeScript change should leave boring evidence behind:
- A small diff.
- Clear types at the boundary.
- No unexplained escape hatches.
- Tests for behavior the compiler cannot prove.
- Typecheck and lint results.
- A short explanation of assumptions.
That is responsible AI use in a TypeScript repo: use the assistant for speed, use types and tests for evidence, and keep your name on code you understand.
This closes the AI section. The next part starts applied TypeScript tracks, where the same habits carry forward: explicit boundaries, strict checks, and no trust without evidence.
Checkpoint
Answer all three to mark this lesson complete