将传入的 JSON 对象映射到打字稿接口

Map incoming JSON Object to typescript interface

有没有办法将传入的 JSON 对象映射到 typescript 接口?

所以,让我解释一下。我试过使用 class-transformer,但它并没有解决我的问题。在 javascript 中,我会使用 object-mapper 从源转换到目标。我的传入对象的键可以是大写、小写、带连字符或下划线,但它们会映射到相同的界面。例子

传入对象

{
  'FIRST NAME': 'John',
  'last_name' : 'Doe',
  'Email Address': 'John.Doe@example.com' 
}

我想将其映射到

{
  'first_name': 'John',
  'last_name': 'Doe',
  'email_address': 'John.Doe@example.com'
}

class-transformer 的问题是我只能在 Expose 中使用一个可以从传入对象映射到的名称。

如何在打字稿中解决这个问题?

您可以使用以下 TS 功能来完成此操作:

我们将使用通用 Split 类型拆分它,并按 (space) 字符拆分,将其替换为 _(下划线) .在这种情况下,我们使用递归策略来完成此操作。

我从type-fest, and inspired it my answer from their various change case types

那里借用了Split类型
// Taken from type-fest https://github.com/sindresorhus/type-fest/blob/main/source/split.d.ts
type Split<
    S extends string,
    Delimiter extends string,
> = S extends `${infer Head}${Delimiter}${infer Tail}`
    ? [Head, ...Split<Tail, Delimiter>]
    : S extends Delimiter
    ? []
    : [S];

type ConvertSpaceToUnderscore<Parts extends readonly any[], PreviousPart = never> = 
    Parts extends [`${infer FirstPart}`, ...infer RemainingParts]
    ? FirstPart extends undefined
        ? ''
            : FirstPart extends ''
                ? ConvertSpaceToUnderscore<RemainingParts, PreviousPart>
                : RemainingParts extends {length: 0} ? Lowercase<FirstPart> : `${Lowercase<FirstPart>}_${ConvertSpaceToUnderscore<RemainingParts, PreviousPart>}`
        : '';

type Convert<T extends Record<string, string>> = {
    [K in keyof T as
        K extends string ? ConvertSpaceToUnderscore<Split<K, ' '>> : never
    ]: T[K]
}

然后在你的类型上使用它

type Input = {
  'FIRST NAME': 'John',
  'last_name' : 'Doe',
  'Email Address': 'John.Doe@example.com' 
}

type Converted = Convert<Input>
// =>
{
  first_name: "John";
  last_name: "Doe";
  email_address: "John.Doe@example.com"
}

TS Playground

上查看实际效果

您可以根据需要添加自己的拆分器以转换任何其他字符。

此类型可以作为 return 值简单地应用于 object-to-object 映射器实用程序的任何实现。