消除 any;优先使用 unknown 并进行收窄
用 unknown 和类型收窄替代 any;添加小型守卫和断言函数;逐步切换严格性标志,同时避免破坏构建。
消除 any;优先使用 unknown 并进行收窄 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 1 节课,共 2 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 2 节课。
简介
目标:消除 any 的高风险点。对于不受信任的值,优先使用未知类型,并通过简单检查进行收窄。您将添加小型守卫,并逐步启用严格标志。
- 任意类型 → 未知类型
- 使用 typeof/in/instanceof 进行收窄
- 断言函数
any 类型的陷阱
any 会关闭安全检查:错误的结构或字符串运算可能在编译时漏过,直到之后才失败。
// any hides bugs
function avgBad(values: any): number {
// Compiles even if values is not an array of numbers
return values.reduce((a: number, b: number) => a + b, 0) / values.length
}
// Runtime crash examples:
// avgBad(123)
// avgBad(["1","2"]) // string addition!未知类型与收窄
对于来自外部的输入,请使用 unknown。使用 Array.isArray 和 typeof 进行收窄,然后安全地执行计算。
// unknown forces checks
function avg(values: unknown): number {
if (!Array.isArray(values)) throw new Error("values must be an array")
const nums = values.filter((v): v is number => typeof v === "number")
if (nums.length === 0) throw new Error("no numbers")
const sum = nums.reduce((a, b) => a + b, 0)
return sum / nums.length
}
// avg([1,2,3]) → 2; avg("oops") throws early with a clear message类型守卫
创建一个谓词 x is T,以便干净地收窄调用方的类型。让守卫保持小巧,只关注结构检查。
// Small predicate to reuse narrowing
export type User = { id: string; name: string }
export function isUser(x: unknown): x is User {
return typeof x === "object" && x !== null
&& typeof (x as any).id === "string"
&& typeof (x as any).name === "string"
}
export function hello(x: unknown) {
if (!isUser(x)) throw new Error("invalid user")
return `Hello, ${x.name}`
}断言函数
断言函数(asserts x is T)在执行后会进行类型收窄。请将其用于必需的前置条件,并使用清晰的消息抛出错误。
// Assertion function throws or narrows
function assertUser(x: unknown): asserts x is { id: string; name: string } {
if (typeof x !== "object" || x === null) throw new Error("not an object")
const o = x as Record<string, unknown>
if (typeof o.id !== "string" || typeof o.name !== "string") throw new Error("bad user")
}
export function greetUnsafe(x: unknown) {
assertUser(x) // now x is narrowed after this call
return `Hi ${x.name}`
}严格性计划
计划:
- 启用
noImplicitAny,并先修复新出现的错误。 - 为外部输入引入守卫。
- 启用
strictNullChecks,并显式处理未定义值。 - 使用 ESLint 跟踪剩余的
any,并逐步减少其使用。
未知类型与 any 检查
快速检查:对于不受信任的数据,为什么优先使用 unknown 而不是 any?
回顾
回顾:用 unknown 替换 any,添加小型守卫或断言,并分小步提高严格标志,以保持构建通过。
常见问题解答
「消除 any;优先使用 unknown 并进行收窄」课时是免费的吗?
是的 — 「消除 any;优先使用 unknown 并进行收窄」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 2 节课。
「消除 any;优先使用 unknown 并进行收窄」这节课中我会学到什么?
用 unknown 和类型收窄替代 any;添加小型守卫和断言函数;逐步切换严格性标志,同时避免破坏构建。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 2 节。
「消除 any;优先使用 unknown 并进行收窄」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 消除 any;优先使用 unknown 并进行收窄
- 逐步启用严格标志