前端写 nestjs 后端,用 TypeORM 时感到非常困惑,不知道是不是我的理解有问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shintendo
V2EX    TypeScript

前端写 nestjs 后端,用 TypeORM 时感到非常困惑,不知道是不是我的理解有问题

  •  
  •   shintendo 2024-08-25 14:57:19 +08:00 3019 次点击
    这是一个创建于 413 天前的主题,其中的信息可能已经有所发展或是发生改变。
    当我把一个表字段定义为 nullable: true 或者 nullable: false 的时候,似乎并不影响这个字段在代码里是 optional 还是 required ?如果我不通过 ORM 自动建表,而是自己在 navicat 里建表,那是不是 TypeORM 里面的 @Column 装饰器参数就没有任何意义?

    另一个更大的疑问:我定义一个 Entity ,所有字段都是 Not Null 的,类型也都是 required 的,结果 TypeORM 允许我往这个表里保存空对象?等着数据库报错?
    这个类型安全体现在哪里,我真的很迷惑,网上搜了一圈没看到有人问这个,不禁怀疑是我的理解有问题


    11 条回复    2024-08-26 11:53:00 +08:00
    superedlimited
        1
    superedlimited  
       2024-08-25 15:26:37 +08:00 via iPhone
    这是基础知识问题,建议深入学习一下面向对象。
    shintendo
        2
    shintendo  
    OP
       2024-08-25 15:44:41 +08:00
    @superedlimited
    本质上我的问题是 TypeORM 的 insert/save 方法为什么接受 Partial<Entity>而不是 Entity 的参数,没看出这跟面向对象有什么关系?
    XCFOX
        3
    XCFOX  
       2024-08-25 15:53:12 +08:00   5
    TypeORM

    > 当我把一个表字段定义为 nullable: true 或者 nullable: false 的时候,似乎并不影响这个字段在代码里是 optional 还是 required ?

    是的,装饰器无法影响 class 内属性的类型。


    > 如果我不通过 ORM 自动建表,而是自己在 navicat 里建表,那是不是 TypeORM 里面的 @Column 装饰器参数就没有任何意义?

    不完全是,@Column 装饰器参数的主要作用就是生成简表语句,其次 TypeORM 在运行时会通过装饰器参数(元数据)做一些判断,避免一些错误的 SQL 。

    > 我定义一个 Entity ,所有字段都是 Not Null 的,类型也都是 required 的,结果 TypeORM 允许我往这个表里保存空对象?等着数据库报错?

    是的,装饰器无法影响 class 内属性的类型。但为了更好的类型安全你应该在 tsconfig.json 中配置 strictPropertyInitialization 为 ture ,并为每个属性声明是否为 nullable ( https://typescriptlang.org/tsconfig/#strictPropertyInitialization )

    我个人建议你尽早抛弃 TypeORM ,TypeORM 项目已经不再积极维护了。换更严谨 mikro-orm ( https://mikro-orm.io/ ),mikro-orm 能通过 ts-morph 从 class property 提取类型以及 nullable ,能够避免装饰器内 nullable 属性与 class property 声明的 nullable 不一致的情况
    https://mikro-orm.io/docs/defining-entities
    Chemist
        4
    Chemist  
       2024-08-25 15:58:09 +08:00 via iPhone   2
    因为实体判空不应该在 DAO 层做。

    即使编译时类型检测 check 住了,运行时对象仍然有可能是空的,还得报运行时异常。
    superedlimited
        5
    superedlimited  
       2024-08-25 16:23:53 +08:00 via iPhone
    @shintendo 不要狡辩了。不仅面向对象基础不行,ts 基础也不行。不是会拼写 partial 就是掌握了 ts 了,partial 是 required 的反面么?
    yor1g
        6
    yor1g  
       2024-08-25 16:43:34 +08:00   1
    number 你返回个 string 都行 type 只是限制编译 实际还是 js
    注解上面的声明实际用了创建表结构
    IvanLi127
        7
    IvanLi127  
       2024-08-25 17:27:04 +08:00   1
    TypeORM 好像提供不了太多的类型安全,这个是正常现象,prisma 这种会更安全些。这是 TypeORM 的定位和你预期不同。
    shintendo
        8
    shintendo  
    OP
       2024-08-26 10:29:54 +08:00
    @XCFOX
    谢谢你的回答,清楚多了。确实想着换其它的 ORM ,只是不确定其它 ORM 是不是也这样,我去试试 mikro-orm 。
    shintendo
        9
    shintendo  
    OP
       2024-08-26 10:34:55 +08:00
    @kyuuseiryuu
    “运行时对象仍然有可能是空的”是指比如前端传过来的参数不对?所以需要运行时校验?
    shintendo
        10
    shintendo  
    OP
       2024-08-26 11:10:36 +08:00
    @superedlimited
    “partial 是 required 的反面么?”
    ![]( )
    Chemist
        11
    Chemist  
       2024-08-26 11:53:00 +08:00   1
    @shintendo #9 是这样的。系统架构上 controller 层要保证所有的业务参数是合法的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2841 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 13:50 PVG 21:50 LAX 06:50 JFK 09:50
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86