gpt4 book ai didi

javascript - 不属于 TypeScript 类型的自动跳过属性

转载 作者:搜寻专家 更新时间:2023-10-30 21:05:20 32 4
gpt4 key购买 nike

假设我有以下类型声明:

declare type Point2D = { x: number, y: number }

我从服务器获取一些数据并得到以下信息:

const response = { x: 1.2, y: 3.4, foreign1: 'value', foreign2: 'value' }

是否可以自动忽略所有不属于我的类型的属性?像这样:

const point: Point2D = response // Should skip all props except for 'x' and 'y'

重要的是响应可以有任意数量的外部属性,所以我不能将对象解构与 rest 运算符一起使用。

最佳答案

类型在运行时不可用。

为了让事情变干,可以使用辅助定义对象:

const Point2DDefinition = { x: 1, y: 1 };
type Point2D = typeof Point2DDefinition;

const point: Point2D = Object.entries(response)
.filter(([k]) => Object.keys(Point2DDefinition).includes(k))
.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {} as Point2D);

由于定义对象依赖于推断类型,它有一定的局限性,例如不能使用交集或联合类型(一个值不能同时是数字和字符串)。

请注意,此代码不包含 point 的检查具有 Point2D 的所有属性, 所以从技术上讲它更像是 point: Partial<Point2D> .它也不检查值是否与定义中的类型相同。

可以在运行时额外提供这两种检查以确保类型安全。

或者,Point2D可以转换为一个类,该类负责在构造时省略不必要的属性。

应明确列出属性:

class Point2D {
x: number;
y: number;

constructor({ x, y }: Point2D) {
this.x = x;
this.y = y;
}
}

可以选择将验证添加到类构造函数中以确保运行时的类型安全。

不显式列出属性的解决方法是将类与辅助定义对象组合以迭代对象属性。 Declaration merging可用于断言 Point2D类具有 Point2DDefinition 中列出的所有属性:

type TPoint2D = typeof Point2DDefinition;

interface Point2D extends TPoint2D {};
class Point2D {
constructor(point: Point2D) {
for (const k of Object.keys(Point2DDefinition)) {
// runtime check for value types can also be added
if (k in point) {
this[k] = point[k];
} else {
throw new TypeError();
}
}
}
}

The important thing is that the reponse can have any number of foreign properties, so I cannot use object destructuring with the rest operator.

对象解构会生成 WET 但类型安全(在编译时)的代码,当然可以用于此目的,例如:

const point: Point2D = (({ x, y }) => ({ x, y }))(response as Point2D);

它不需要 ...rest的属性,因为它们应该被丢弃。

关于javascript - 不属于 TypeScript 类型的自动跳过属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50378162/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com