javascript 将从后端接收到的数据以 typescript 的形式转换到前端接口[复制]

2ekbmq32  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(109)

此问题已在此处有答案

TypeScript object type casting, when the two objects differ by key name(s)(1个答案)
TypeScript: transform one interface to another(2个答案)
20小时前关闭。
我从后端收到的数据如下:

id: number;
  user_id: number;
  car_brand: string;
  car_model: string;
  vin: string;
  equipment: string;
  reg_number: string;
  car_mileage: number;
  car_year: string;

我在前端有一个接口如下:UserCarType

id: number;
  user_id: number;
  brand: string;
  model: string;
  vin: string;
  restyling:string
  govtNumber: string;
  mileage: number;
  year: string;

正如你所看到的,这两个类型是相同的,但只有preoprty名称不同,我如何将从后端接收到的类型转换为前端接口?
我试图使用“作为”关键字,但没有成功,仍然与后端名称preoperties。我发现了一些来源,他们谈论Map,并创建一个Map每个功能的函数,请有人为我提供最好的和有效的解决方案?
我也试过这个:

const car = {
    id: props.userCar.id,
    user_id: props.userCar.user_id,
    user_guid: props.userCar.user_guid,
    car_guid: props.userCar.car_guid,
    color_guid: props.userCar.color_guid,
    brand_guid: props.userCar.brand_guid,
    model_guid: props.userCar.model_guid,
    brand: props.userCar.car_brand,
    model: props.userCar.car_model,
    vin: props.userCar.vin,
    equipment: props.userCar.equip,
    govtNumber: props.userCar.reg_num,
    mileage: props.userCar.mileage,
    year: props.userCar.manuf_date,
    predictedPrice: props.userCar.sale_price,
    brandImage: props.userCar.logo,
    carImage: '', // Set the carImage property based on your data}
  };

但是我想知道是否有一种方法可以用 typescript 正确地完成它。

k10s72fa

k10s72fa1#

其他一些语言提供了运行时的“转换”,但TypeScript不能这样做,因为它只存在于编译时(而不是运行时)。TypeScript中唯一的“强制转换”只是简单地进行编译时typeAssert(编译器重写),这对运行时程序数据(只是类型)没有影响。
如果您要将值从输入对象复制到新对象,但您希望将值复制到可能与原始键不同的键:您可能需要一个函数来帮助完成该任务,这样您所需要做的就是指定输入属性名称到输出属性名称的Map。下面是这样一个函数的例子,你可以修改它以满足你的需要:
TSPlayground

type MappedKeys<
  PropertyMap extends Readonly<Record<string, string>>,
  Input extends Readonly<Record<keyof PropertyMap, any>>,
> = { -readonly [K in keyof PropertyMap as PropertyMap[K]]: Input[K] };

function mapKeys<
  const PropertyMap extends Readonly<Record<string, string>>,
  Input extends Readonly<Record<keyof PropertyMap, any>>,
>(propertyMap: PropertyMap, input: Input): MappedKeys<PropertyMap, Input> {
  const result = {} as MappedKeys<PropertyMap, Input>;
  // @ts-expect-error
  for (const key in propertyMap) result[propertyMap[key]] = input[key];
  return result;
}

type ServerCar = {
  id: number;
  user_id: number;
  car_brand: string;
  // …etc.
};

const serverCar: ServerCar = {
  id: 101,
  user_id: 5432,
  car_brand: "AutoCorp",
  // …etc.
};

type ClientCar = {
  id: number;
  user_id: number;
  brand: string;
  // …etc.
};

const clientCar: ClientCar = mapKeys({
  id: "id",
  user_id: "user_id",
  car_brand: "brand",
  // …etc.
}, serverCar);

console.log(clientCar); //=> { id: 101, user_id: 5432, brand: "AutoCorp" }
ar5n3qh5

ar5n3qh52#

首先,强化@Sergey Sosunov所说的,这个属性Map任务没有直接的TypeScript语法。as关键字不适合类型Assert。换句话说,它将对象视为另一种类型,而不是编译器推断的对象类型。
此外,将Map逻辑与后端解耦是有利的,因为它将代码与潜在的后端更改隔离开来,并确保了更有弹性的应用程序结构。
正如@Sergey指出的那样,使用DTO服务可以作为一种实用的解决方案,确保一致和准确的数据传输。

相关问题