有没有办法使用typescript zod库来解析类示例

pdsfdshx  于 2022-12-27  发布在  TypeScript
关注(0)|答案(1)|浏览(153)

我使用Zod验证库和typescript已经有一段时间了,我很喜欢它。
这可能是一个非常基本的问题,但我正在尝试找出用类类功能扩展Zod Schema的最佳模式。
为了便于示例,我们使用如下Vector3模式:

const Vector3Schema = z.object({
    x: z.number(),
    y: z.number(),
    z: z.number(),
})

type Vector3 = z.infer<typeof Vector3Schema>;

这是非常好的类型与zod验证相关联。没有重复的定义,非常干净。我喜欢它。
问题是我应该如何继续用一些类的功能来扩展Vector3类型。
也许这是我的OOP背景的闪光点,但我希望有一些基本的功能以类的方式与类型相关联,所以它可以像这样使用:

let vec1 = Vector3Schema.parse({x:1, y: 2, z: 3});
let vec2 = Vector3Schema.parse({x:4, y: 5, z: 6});
let distance = vec1.distance(vec2);
vec1.normalize();

我可以只为Vector3创建一个单独的类定义,并只使用Zod来验证传递给构造函数的数据,但这很快就会导致同样的老问题:必须分别维护类定义和确认逻辑。
所以我想问题是:是否有一种方便方法可以将Zod模式解析为类示例?2或者用附加功能扩展解析的类型?
或者...我应该放弃我爷爷的OOP方式,以更多功能的风格前进:

function normalize(v: Vector3) {...}
function distance(v1: Vector3, v2: Vector3) {...}

let vec1 = Vector3Schema.parse({x:1, y: 2, z: 3});
let vec2 = Vector3Schema.parse({x:4, y: 5, z: 6});
let distance = distance(vec1, vec2);
vec1 = normalize(vec1);

我很想听听你对这个主题的看法。

hfyxw5xn

hfyxw5xn1#

看起来这已经在这里讨论了Javascript:https://github.com/colinhacks/zod/issues/641
建议的想法是使用工厂函数来扩展对象。也许这可以修改为与 typescript 一起使用。需要研究一下这个问题。
更新:
经过一些测试后,我提出了这个解决方案:

const Vector3Schema = z.object({
    x: z.number(),
    y: z.number(),
    z: z.number(),
  });

  interface Vector3 extends z.infer<typeof Vector3Schema> {
    normalize: () => void;
    distance: (v: Vector3) => number;
  }

  function parseVector3(data: unknown): Vector3 {
    return {
      ...Vector3Schema.parse(data),
      normalize: function () { /*...*/ },
      distance: function(v: Vector3) { /*...*/}
    };
  }

现在,使用所有良好的 typescript 的用例是:

let vec1 = parseVector3({x:1, y: 2, z: 3});
let vec2 = parseVector3({x:4, y: 5, z: 6});
let distance = vec1.distance(vec2);
vec1.normalize();

请让我知道,如果有更好或更优雅的解决方案的问题。

相关问题