【问题标题】:Convert Object<T> to Object<A> where A is contained in T将 Object<T> 转换为 Object<A>,其中 A 包含在 T 中
【发布时间】:2021-02-02 15:52:13
【问题描述】:

我正在使用 Prisma 为我的数据库数据生成架构和模型。
在那里,我定义了一个“用户”模型,其中包含这些数据(类型由 Prisma 自动生成):

type User {
    name: string,
    nickName: string,
    sensitiveInfo1: string,
    sensitiveInfo2: string
}

但是,当我的客户请求此数据时,我无法在响应负载中发送敏感信息。

Prisma 有一种非常方便的方式来定义自定义类型:

import { UserGetPayload } from "./prisma/src/generated/client"

// now I define a custom type
export type UserPublicInfo = UserGetPayload<{
    select: {
        name: true,
        nickName: true,
    }
}>

// this gives me the type:
// type UserPublicInfo {
//        name: <whatever type name is in the schema>,
//        nickName: <whatever type nickName is in the schema>
// }

现在,假设我已经从数据库中检索了一个 User 类型的用户实例。我不想以响应负载仅包含“UserPublicInfo”信息的方式将其转换为“UserPublicInfo”。

如果我像user as UserPublicInfo 那样投射用户类型的对象,则类型建议指向正确的方向,仅显示子类型的属性。但是,敏感数据仍然存在。

我是 javascipt/typescript 的初级人员,但我相信这与对象的原型有关。那我怎么能这样投射呢?

【问题讨论】:

    标签: typescript casting type-conversion prisma prisma2


    【解决方案1】:

    这个问题有两个部分,如何告诉 typescript 属性已经消失以及如何实际删除它们。

    打字稿

    您正在寻找的是打字稿实用程序PickOmit

    仅从User 获取字段namenickName

    type UserPublicInfo = Pick<User, 'name' | 'nickName'>
    

    User 获取除sensitiveInfo1sensitiveInfo2 之外的所有字段:

    type UserWithoutPrivate = Omit<User, 'sensitiveInfo1' | 'sensitiveInfo2'>
    

    在您给出的示例中,这两种类型都是相同的并且解析为

    type UserPublicInfo = {
        name: string;
        nickName: string;
    }
    

    Javascript

    现在用于删除属性。最简单的方法是使用包lodash 中的pickomit 函数。它们具有内置的打字稿支持,因此您无需了解我刚刚告诉您的任何 TS 内容。

    如果你想自己做,你可以使用扩展运算符删除你不想要的属性(注意:一些 linter 会在这里抱怨未使用的变量)。

    export const userToPublic = (user: User): UserPublicInfo => {
        const {sensitiveInfo1, sensitiveInfo2, ...rest} = user;
        return user;
    }
    

    Typescript Playground Link

    【讨论】:

    • 你的答案很完美!谢谢你。有什么方法可以告诉 lodash 或 typescript 本身选择子类型定义的所有元素?像 _.pick(User, UserPublicInfo)。这比显式选择由子类型定义的属性要好得多。
    • 顺便说一句,您在 TS 操场链接中示例的最后一行有点坏了,您也注意到了吗?
    猜你喜欢
    • 2016-04-14
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多