在 TypeScript 中将从后端接收的数据投射到前端接口 [重复]

cast data received from backend to a frontend interface in typescript [duplicate]

提问人:Zero0 提问时间:10/13/2023 最后编辑:Zero0 更新时间:10/13/2023 访问量:91

问:

我从后端收到的数据如下:

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

我在前端有一个界面,如下所示: 用户汽车类型

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

正如你所观察到的,这两种类型是相同的,但只有preoprty名称不同,我怎样才能将从后端接收到的类型投射到前端接口?

我尝试使用“as”关键字,但没有成功,仍然使用后端名称。 我找到了一些他们谈论映射的来源,并创建映射每个功能的功能,请有人为我提供最佳和有效的解决方案?

我也试过这个:

  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 中正确完成它

javascript reactjs typescript react-native cast

评论

0赞 b_dubb 10/13/2023
请尝试创建自己的解决方案,并在此处发布代码。
0赞 Zero0 10/13/2023
我正在寻求解决方案,itry“as”关键字。我什至不知道我们是否能做到这一点,所以我在问。
0赞 Sergey Sosunov 10/13/2023
关键字在这里对您没有帮助,我不建议使用它,因为它只会打字脚本忽略所有可能的类型错误。如果您进行了手动映射,但仍然看到“服务器属性” - 那么问题出在其他地方。至于我 - 最好的解决方案是创建一个带有映射的目录,该目录将 DTO 模型(您从服务器获得的数据)映射到您的实际模型(即 就是这样。asexport function mapUserCarType(input: UserCarTypeDTO): UserCarType {.....}
0赞 Zero0 10/13/2023
''' const propertyMapping = { car_brand: 'brand', car_model: 'model', equip: 'equipment', reg_num: 'govtNumber', manuf_date: 'year', sale_price: 'predictedPrice', logo: 'brandImage', };const car = Object.fromEntries( Object.entries(props.userCar).map(([key, value]) => [ propertyMapping[key] || key, value, ]), );'''你怎么看这种方法?
0赞 jcalz 10/13/2023
你必须自己实现一个解决方案,在Typescript中没有单一的“正确”方法可以做到这一点,在类型系统中也没有一个神奇的自动方法(它没有运行时效果)

答:

1赞 Ny Randriantsarafara 10/13/2023 #1

首先,为了强化 @Sergey Sosunov 所说的内容,这个属性映射任务没有直接的 TypeScript 语法。该关键字不适合类型断言。换言之,它将对象视为编译器推断对象的类型之外的另一种类型。as

此外,像你一样将映射逻辑与后端分离是有利的,因为它将你的代码与潜在的后端更改隔离开来,顺便说一下,确保应用程序结构更具弹性。

正如@Sergey所指出的,使用DTO服务可以作为一种实用的解决方案,确保数据传输的一致性和准确性。

1赞 jsejcksn 10/13/2023 #2

其他一些语言提供运行时“强制转换”,但 TypeScript 不能这样做,因为它只存在于编译时(而不是运行时)。TypeScript 中唯一的“强制转换”只是进行编译时类型断言(编译器覆盖),这对运行时程序数据(只是类型)没有影响。

如果要将值从输入对象复制到新对象,但希望将值复制到可能与原始值不同的键:您可能需要一个函数来帮助完成该任务,以便只需指定输入属性名称到输出属性名称的映射即可。下面是此类函数的示例,您可以根据需要进行修改:

TS 游乐场

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" }