如何优雅处理TypeScript中联合类型值的类型判断问题?
优雅处理TypeScript联合类型的类型收窄问题
嘿,这个场景我经常碰到!处理TypeScript里string | Product这种联合类型的类型收窄,确实有比每次写typeof item.product === 'object'更优雅的方式,给你分享几个我常用的方案:
1. 自定义类型守卫函数(推荐,复用性高)
把类型检查逻辑抽成一个可复用的类型守卫函数,让代码更清晰,也方便在多个地方使用:
// 定义类型守卫函数,明确返回类型为"product is Product" function isProduct(product: string | Product): product is Product { // 这里可以加更严谨的判断,比如确保不是null且存在_id属性 return typeof product === 'object' && product !== null && '_id' in product; } // 遍历数组时使用 items.forEach(item => { if (isProduct(item.product)) { // TypeScript现在能明确知道item.product是Product类型 console.log(item.product._id); } else { // 这里处理product是string的情况 console.log('Product ID string:', item.product); } });
2. 使用区分联合类型(从设计层面优化)
如果业务上product的两种类型(string和Product)代表不同的含义(比如string是产品ID,Product是完整产品对象),可以重构接口为区分联合类型,让类型逻辑更清晰:
// 拆分出两种明确的Item类型 interface FullProductItem { kind: 'full-product'; product: Product; } interface ProductIdItem { kind: 'product-id'; product: string; } // 重新定义Item为两种类型的联合 type Item = FullProductItem | ProductIdItem; // 遍历时通过区分字段自动收窄类型 items.forEach(item => { if (item.kind === 'full-product') { console.log(item.product._id); // 类型自动识别为Product } else { console.log('需要根据ID查询产品:', item.product); // 类型自动识别为string } });
3. 类型断言(谨慎使用)
如果你能100%确定当前遍历到的item.product一定是Product类型(比如业务逻辑已经过滤过),可以用类型断言快速跳过检查,但要注意风险——如果断言错误会导致运行时问题:
items.forEach(item => { // 断言为Product类型,仅在确定类型时使用 const product = item.product as Product; console.log(product._id); });
4. 可选链+空值合并(快速处理取值场景)
如果只是想安全获取_id并设置默认值,不想写完整的分支判断,可以用可选链和空值合并操作符:
items.forEach(item => { // 用类型断言配合可选链,安全获取_id,不存在时用默认值 const productId = (item.product as Product)?._id ?? 'unknown-id'; console.log(productId); });
内容的提问来源于stack exchange,提问作者Timothy
相关产品推荐
相关产品推荐

