typescript 是否有更好的方法将一种类型的属性Map到另一种类型?

bjg7j2ky  于 2023-04-13  发布在  TypeScript
关注(0)|答案(1)|浏览(284)

我们目前从数据库中获取对象,其类型如下:

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

我试着把它变成这样:

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

目前,我正在做的是创建一个函数,通过执行以下操作将一个Map到另一个:

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

它看起来很乏味。在做了一些研究之后,我发现我可能可以使用map函数,但我仍然在将一个赋值给另一个。我读了一些关于Mapped类型的文章,但它们似乎更多地是关于扩充而不是完整的转换。
有没有比我现在所做的更好的方法来将一种类型Map到另一种类型?

qv7cva1a

qv7cva1a1#

下面简单介绍一下模式库(如Zod)的使用。
我们的想法是定义模式并使用transform功能来重新Map键,这样可以保留数据的形状(并可能允许更时髦的转换,如日期提取),而无需重复类型声明。

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
它可能 * 稍微 * 不那么乏味,但我推荐它将外部数据带入折叠,因为Zod会大声告诉你是否有模式冲突。

相关问题