将传入的 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"
}
上查看实际效果
您可以根据需要添加自己的拆分器以转换任何其他字符。
此类型可以作为 return 值简单地应用于 object-to-object 映射器实用程序的任何实现。
有没有办法将传入的 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"
}
上查看实际效果
您可以根据需要添加自己的拆分器以转换任何其他字符。
此类型可以作为 return 值简单地应用于 object-to-object 映射器实用程序的任何实现。