如何减少 javascript 对象以仅包含来自界面的属性 [英] How to reduce javascript object to only contain properties from interface

查看:13
本文介绍了如何减少 javascript 对象以仅包含来自界面的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用打字稿时,声明的接口可能如下所示:

When using typescript a declared interface could look like this:

interface MyInterface {
  test: string;
}

具有额外属性的实现可能是这样的:

And an implementation with extra property could be like this:

class MyTest implements MyInterface {
  test: string;
  newTest: string;
}

示例(这里的变量reduced"仍然包含属性newTest"):

Example (here the variable 'reduced' still contain the property 'newTest'):

var test: MyTest = {test: "hello", newTest: "world"}

var reduced: MyInterface = test; // something clever is needed

问题

一般来说,如何使 'reduced' 变量只包含在 'MyInterface' 接口中声明的属性.

In a general way, how can you make the 'reduced' variable to only contain the properties declared in the 'MyInterface' interface.

为什么

在将 angular.toJson 发送到 rest 服务之前尝试使用 'reduced' 变量时会出现问题 - toJson 方法转换 newTest 变量,即使它在编译期间在实例上不可访问,这使得休息服务不接受 json,因为它具有不应该存在的属性.

The problem occur when trying to use the 'reduced' variable with angular.toJson before sending it to a rest service - the toJson method transforms the newTest variable, even if it's not accessible on the instance during compile, and this makes the rest service not accept the json since it has properties that shouldn't be there.

推荐答案

这是不可能的.原因是 interface 是一个 Typescript 结构和 转译的JS代码为空

It is not possible to do this. The reason being interface is a Typescript construct and the transpiled JS code is empty

//this code transpiles to empty!
interface MyInterface {
  test: string;
}

因此在运行时没有什么可处理"的 - 不存在可供查询的属性.

Thus at runtime there is nothing to 'work with' - no properties exist to interrogate.

@jamesmoey 的回答解释了实现预期结果的解决方法.我使用的类似解决方案只是将接口"定义为一个类 -

The answer by @jamesmoey explains a workaround to achieve the desired outcome. A similar solution I use is simply to define the 'interface' as a class -

class MyInterface {
  test: string = undefined;
}

然后您可以使用 lodash 从接口"中选择属性以注入您的对象:

Then you can use lodash to pick the properties from the 'interface' to inject into you object:

import _ from 'lodash';  //npm i lodash

const before = { test: "hello", newTest: "world"};
let reduced = new MyInterface();
_.assign(reduced , _.pick(before, _.keys(reduced)));
console.log('reduced', reduced)//contains only 'test' property

参见 JSFiddle

这是一个实用的解决方案,它对我很有帮助,而不会陷入关于它实际上是接口和/或命名约定的语义上(例如 IMyInterfaceMyInterface) 并允许您模拟和单元测试

This is a pragmatic solution that has served me well without getting bogged down on semantics about whether it actually is an interface and/or naming conventions (e.g. IMyInterface or MyInterface) and allows you to mock and unit test

这篇关于如何减少 javascript 对象以仅包含来自界面的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆