有没有更好的方式将一个类型的属性映射到另一个类型?

huangapple go评论63阅读模式
英文:

Is there a better way to map the properties of one type to another?

问题

We currently get objects from a database with a type like:

type SomeEntity = {
    a: string,
    b: string,
    c: {d: string, e: string}[]
}

And I'm trying to get it into something like:

type Converted = {
    heading: string,
    copy: string,
    links: { label: string, url: string }[]
}

Currently, what I'm doing is creating a function that maps one to the other by doing something like:

function convert(data: SomeEntity) {
    return {
        heading: data.a,
        copy: data.b,
        links: { label: data.c.d, url: data.c.e }[]
    } as Converted
}

It just seems so tedious. After doing some research, I saw that I can probably use the map function, but I'm still assigning one to another. I read a bit about Mapped types, but they seem more about augmenting rather than full-on conversions.

Is there a better way to map one type to another type than what I'm currently doing?

英文:

We currently get objects from a database with a type like:

type SomeEntity = {
    a: string,
    b: string,
    c: {d:string, e:string}[]
}

And I'm trying to get it into something like:

type Converted = {
    heading:string,
    copy: string,
    links: {label:string, url:string}[]
}

Currently, what I'm doing is creating a function that maps one to the other by doing something like:

function convert(data:SomeEntity)
{
    return {
        heading: data.a,
        copy: data.b,
        links: {label:data.c.d, url:label.data.e}[]
    } as Converted
}

It just seems so tedious. After doing some research, I saw that I can probably use the map function, but I'm still assigning one to another. I read a bit about Mapped types, but they seem more about augmenting rather than full on conversions.

Is there a better way to map one type to another type than what I'm currently doing?

答案1

得分: 1

以下是翻译好的内容:

仅就使用模式库(如Zod)扩展一下的想法 -

这个想法是定义你的模式并使用“transform”功能来重新映射键。它会保留您的数据形状(并且可能允许更酷的转换,如日期提取),而不需要您重复类型声明。

const SomeEntityLink = z.object({
  a: z.string(),
  b: z.string()
}).transform(
  ({ a: label, b: url }) => ({ label, url })
);

const SomeEntity = z.object({
  a: z.string(),
  b: z.string(),
  c: z.array(SomeEntityLink)
}).transform(
  ({ a: heading, b: copy, c: links }) => ({ heading, copy, links })
);

const parsed = SomeEntity.parse({ a: "foo", b: "bar", c: [] });
// { heading: "foo", copy: "bar", links: [] }

在线编辑器

这可能最多略显繁琐,但我建议用它将外部数据引入项目,因为Zod会大声告诉您是否存在模式违规。

英文:

Just to expand briefly on the use of a schema library such as Zod

The idea would be to define your schemas and use the transform functionality to remap the keys. It would preserve the shape of your data (and potentially allow funkier transformations like Date extraction) without you needing to duplicate the type declarations.

const SomeEntityLink = z.object({
  a: z.string(),
  b: z.string()
}).transform(
  ({ a: label, b: url }) => ({ label, url })
);

const SomeEntity = z.object({
  a: z.string(),
  b: z.string(),
  c: z.array(SomeEntityLink)
}).transform(
  ({ a: heading, b: copy, c: links }) => ({ heading, copy, links })
);

const parsed = SomeEntity.parse({ a: "foo", b: "bar", c: [] });
// { heading: "foo", copy: "bar", links: [] }

Sandbox

It is perhaps marginally less tedious at best but I would recommend it for bringing external data into the fold because Zod will tell you loudly if there is a schema violation.

huangapple
  • 本文由 发表于 2023年4月10日 20:55:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75977322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定