Javascript 自动跳过不属于TypeScript中类型的属性
假设我有以下类型声明:Javascript 自动跳过不属于TypeScript中类型的属性,javascript,typescript,Javascript,Typescript,假设我有以下类型声明: 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
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
可以转换为一个类,该类负责在构造时忽略不必要的属性
属性应明确列出:
class Point2D {
x: number;
y: number;
constructor({ x, y }: Point2D) {
this.x = x;
this.y = y;
}
}
可以选择将验证添加到类构造函数中,以在运行时实现类型安全
不显式列出属性的解决方法是将类与帮助器定义对象结合起来,以迭代对象属性。可用于断言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();
}
}
}
}
重要的是,响应可以有任意数量的外部属性,因此我不能使用rest操作符进行对象分解
对象分解会产生湿的但类型安全的代码(在编译时),当然可以用于此目的,例如:
const point: Point2D = (({ x, y }) => ({ x, y }))(response as Point2D);
它不需要属性的
…rest
,因为它们应该被丢弃。如果你已经知道你想要的属性,为什么你必须使用rest操作符?简单回答,不。你在运行时没有关于类型的信息,因此你不能基于它的属性创建一个新对象。