如何以类型安全的方式删除User对象的password属性?
类型安全移除User对象中
password属性的正确实现 最优方案:查询时直接排除password(适用于Prisma等ORM)
如果你的db.findUnique是Prisma或类似ORM提供的方法,最安全高效的方式是在查询阶段就不获取password字段,避免后续处理:
const userWithoutPassword = await db.findUnique({ where: { email: input.email }, select: { id: true, email: true, // 列出所有你需要的字段,不要包含password username: true, createdAt: true } }); return userWithoutPassword;
这种方式返回的对象本身就没有password属性,TypeScript会自动推断正确的类型,完全不需要额外处理。
方案1的改进版:解构赋值+未使用变量处理
原方案1的问题是未使用变量的ESLint警告,以及未处理user可能为null/undefined的情况,改进后:
const user = await db.findUnique({ where: { email: input.email } }); if (!user) { // 先处理用户不存在的场景,比如抛出错误或返回null throw new Error("用户不存在"); } // 用下划线接收password变量,避免ESLint未使用变量警告 const { password: _, ...userWithoutPassword } = user; return userWithoutPassword;
这里userWithoutPassword的类型会被TypeScript自动推断为Omit<User, "password">,完全符合类型安全要求,且无需禁用ESLint规则。
方案2的改进版:实现类型安全的omit函数
Lodash的omit返回类型为any,导致TypeScript无法保证类型安全,自己实现一个类型安全的版本即可解决:
// 自定义类型安全的omit函数 function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> { const result = { ...obj }; keys.forEach(key => delete result[key]); return result; } // 使用示例 const user = await db.findUnique({ where: { email: input.email } }); if (!user) { throw new Error("用户不存在"); } const userWithoutPassword = omit(user, ["password"]); return userWithoutPassword;
这个函数的类型定义会让TypeScript准确推断返回值为Omit<User, "password">,不会触发no-unsafe-assignment错误。
原方案问题分析
- 方案1:未处理
user可能为null/undefined的边界情况,且直接禁用ESLint规则不够优雅,改用下划线接收未使用变量即可解决警告。 - 方案2:Lodash的
omit类型定义不够严格,返回any导致类型安全问题,自定义类型安全的omit函数就能解决。 - 方案3:
delete操作会修改原对象,且原User类型中password是必填属性,删除后对象类型与原定义冲突,TypeScript会报错,同时修改原对象也不符合函数式编程的最佳实践。
内容的提问来源于stack exchange,提问作者wongx
相关产品推荐
相关产品推荐

