V2EX Ketteiron
$V2EX
Solana
Give SOL to Copy Address
使用 SOL 向 Ketteiron 打赏,数额会 100% 进入 Ketteiron 的钱包。
 Ketteiron 最近的时间轴更新
Ketteiron
0.2D
0.03D

Ketteiron

V2EX 第 526953 号会员,加入于 2021-01-05 14:53:49 +08:00
今日活跃度排名 12675
根据 Ketteiron 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
Ketteiron 最近回复了
对业务很了解和自己开店没有关联。
我确实对跨境电商很了解,但从没有自己开店的想法,正是因为太了解了。
5 天前
回复了 FlashEcho 创建的主题 程序员 如何优雅地使用 zod
以 drizzle 的数据库 schema 为第一优先级,在此之上派生下一级的用于接口校验、表单验证的 schema 。
现代化的 typescript 工程,要严格遵守 DRY ,不允许在任何地方出现多次重复定义,分离数据库层与业务层实际上与复用逻辑并不冲突,没有写两遍的必要。
无论何时,应该只有一个唯一来源,应用于整个项目,包括前端以及所有中间件服务,并强制保证运行时类型与 ts 类型完全等同。

基于这个理论,不应该直接使用 createInsertSchema 和 createUpdateSchema ,因为它们也是在重复定义并不明确的类型,应该封装一个方法统一给所有下一级 schema 使用。

它可能长这样 const createSchema = (table,labels)=> createInsertSchema(table).pick(labels)
具体代码不贴了,有一些类型体操,需要保证输入限制以及 pick 生效

举个例子,我定义好一张表
export const userTable = pgTable('user', {
...baseTable,
username: varchar({ length: 32 }).notNull().unique(),
password: varchar({ length: 64 }).notNull(),
})
然后这么使用
export const userLoginSchema = createSchema(userTable, {
username: (s) => s.min(4),
password: (s) => s.min(6),
})
因为返回的是一个 zod 对象,可以按照业务逻辑进行 extend 不在数据库中的其他参数,或者根据业务进行覆盖

第一参数接收一个数据库表,以此限制第二参数输入的键名,value 是一个函数,参数是经过 drizzle-zod 生成后的 schema
drizzle-zod 会为 varchar({ length: 32 }) 这样的定义自动生成 z.string().max(32),但是它不会限制最小长度,因此派生的 schema 需要在原来基础上进行补充,或者也可以直接传入一个 zod 对象覆盖。

不应该对业务层暴露一大堆的 optional ,而是严格限定你只能传递什么东西过来,它要么必须有值要么禁止传递,从数据库层一层一层往下传递到所有涉及到的地方,一直到达前端表单,这才是 schema("契约")的正确用法之一。

还有个地方需要注意,这个 schema 不能直接在 monorepo 中被前端/中间件引入,因为包含完整的数据库模式以及用不到的大量运行时函数,直接 import 大概会打包出两百多 k ,需要使用 json-to-zod + zod-to-json(zod4 最新版已内置) 等变通方法,监听 schema 文件自动生成一个新文件并 export 给其他项目。当然因为无法序列化函数,所以 refine 等功能都用不了。

此外我对 createSchema 进行了大量改造,包括强制传递元数据,并在路由/表单通过包装 safeParseAsync 函数解析出适合人类阅读的提示信息:'用户名长度最低为 4 位'、'密码长度最低 6 位'、'缺少 xxx 字段'、'xxx 格式错误',其中'用户名'和'密码'就是我要求传递的提示文本,它同样只能定义一次,还可以进行 i18n 改造,所有其它信息可以通过遍历 code 、origin 、input 等进行填充,社区里大量使用的 zod i18n 库是一个不理想的变通方法,但图省事也可以去用。
6 天前
回复了 ethusdt 创建的主题 Javascript 你们 js 用过双等号吗
@shintendo #24 eslint 已经弃用了 allow-null ,可以传递一个对象例如 ["error", "always", {"null": "ignore"}] 进行排除。https://eslint.org/docs/latest/rules/eqeqeq
我认为 == null 是个不太好的编程习惯,带有隐式判断
我自己无论何时都会显式编写 if (x === null || x === undefined)
不过也没用上几次,在有了 ?. 和 ?? 后,几乎不存在需要使用 ==null 的场景
假榜,两个春熙路都没看见
2025 年 12 月 24 日
回复了 8675bc86 创建的主题 程序员 AI 是不是基本杀死了 blog
@Kirkcong #68 各大中小厂商的文档只能用狗屎来形容,如果再打开官方提供的 SDK 看一下源码更是不堪入目。
const deps = getDeps.call(store, store);
这样的实现必须手动在 getter 写一次,@memo 指定依赖列表,完全依赖约定,把 react 的糟粕带了过来。

useStoreSelector 是通过猜测用户访问了什么属性调用 trackGetterAccess 增加引用计数,有多脆弱我就不说了,至少 StrictMode 会错误计数。此外没处理好竟态条件。

另外 View 层反向控制 Model 的缓存过于反模式,只要没有 React 组件在查看属性,就会直接删掉缓存。
Immer 混搭 weakMap 过于奇葩。

一堆 any ,看一半就没耐心看下去了。
函数式的重点在于不可变更新。

> 费力地模拟着面向对象
不费劲,闭包是穷人的对象。

你说对象=状态+行为

更准确地说
对象=原型链+状态+行为
闭包=状态+行为

get() 和 this 有本质上的区别,this 只会带来 bug 和心智负担。

> 它是“二等公民” :你必须显式地调用它 get(),而且它打破了 JS 引擎对 this 的自然优化。
这是我 2025 年听到最好笑的笑话,比这个还好笑 /t/1177228
2025 年 12 月 19 日
回复了 zhengfan2016 创建的主题 Vue.js 请问 vue3 的 onclick 和 @click 有什么区别
我有个不相关的问题,这位老哥会被疯狂 @吗?
member/click
2025 年 12 月 18 日
回复了 MagicCoder 创建的主题 程序员 从已损坏的备份中拯救数据
不太可能是网络波动导致的,nfs 默认使用 tcp ,tcp 是解决网络不可靠的传输协议,要么完整地传输过去,要么抛出一个错误提示传输失败。
"Corrupted block detected"
"Restored data doesn't match checksum"
这已经说明了文件在存储前/后发生了变更,我是觉得你的内存或者硬盘至少坏了一个,另外系统卡死大概率是相同问题,全部排查一遍吧。
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     879 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 14ms UTC 20:12 PVG 04:12 LAX 12:12 JFK 15:12
Do have faith in what you're doing.
ubao msn 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