如何将javascript对象简化为仅包含来自接口的属性
使用typescript时,声明的接口可能如下所示:如何将javascript对象简化为仅包含来自接口的属性,javascript,angularjs,typescript,Javascript,Angularjs,Typescript,使用typescript时,声明的接口可能如下所示: interface MyInterface { test: string; } class MyTest implements MyInterface { test: string; newTest: string; } 具有额外属性的实现可以如下所示: interface MyInterface { test: string; } class MyTest implements MyInterface { test
interface MyInterface {
test: string;
}
class MyTest implements MyInterface {
test: string;
newTest: string;
}
具有额外属性的实现可以如下所示:
interface MyInterface {
test: string;
}
class MyTest implements MyInterface {
test: string;
newTest: string;
}
示例(此处变量“reduced”仍包含属性“newTest”):
问题
一般来说,如何使“reduced”变量仅包含在“MyInterface”接口中声明的属性
为什么
在将“reduced”变量发送到rest服务之前,尝试将其与angular.toJson一起使用时会出现问题-toJson方法会转换newTest变量,即使在编译期间实例上无法访问该变量,这会使rest服务不接受json,因为它具有不应该存在的属性 在您的示例中,newTest属性不能通过reduced变量访问,因此这就是使用类型的目的。typescript带来类型检查,但它不操纵对象属性。在您的示例中,newTest属性将无法通过reduced变量访问,因此这就是使用类型的目的。typescript带来类型检查,但它不操纵对象属性。您是否仅尝试设置/分配界面上列出的属性?这样的功能在TypeScript中是不可用的,但是编写一个函数来执行您想要的行为非常简单
interface-IPerson{
名称:字符串;
}
类人实现IPerson{
名称:字符串=“”;
}
班级工作人员实施IPerson{
名称:字符串=“”;
位置:字符串=“”;
}
var jimStaff:员工={
名字:“吉姆”,
职位:“程序员”
};
变量jim:Person=newperson();
limitedAssign(jimStaff,jim);
console.log(jim);
函数限制分配(源:T,目标:S):无效{
用于(目标中的var prop){
if(源[prop]&&destination.hasOwnProperty(prop)){
目的地[prop]=源[prop];
}
}
}
是否仅尝试设置/分配界面上列出的属性?这样的功能在TypeScript中是不可用的,但是编写一个函数来执行您想要的行为非常简单
interface-IPerson{
名称:字符串;
}
类人实现IPerson{
名称:字符串=“”;
}
班级工作人员实施IPerson{
名称:字符串=“”;
位置:字符串=“”;
}
var jimStaff:员工={
名字:“吉姆”,
职位:“程序员”
};
变量jim:Person=newperson();
limitedAssign(jimStaff,jim);
console.log(jim);
函数限制分配(源:T,目标:S):无效{
用于(目标中的var prop){
if(源[prop]&&destination.hasOwnProperty(prop)){
目的地[prop]=源[prop];
}
}
}
一般来说,如何使“reduced”变量仅包含在“MyInterface”接口中声明的属性
由于TypeScript是结构化的,这意味着任何包含相关信息的内容都是类型兼容的,因此是可分配的
也就是说,TypeScript1.6将得到一个称为的概念。这将更容易捕捉清楚的打字错误(注意,新鲜度仅适用于对象文字):
一般来说,如何使“reduced”变量仅包含在“MyInterface”接口中声明的属性
由于TypeScript是结构化的,这意味着任何包含相关信息的内容都是类型兼容的,因此是可分配的
也就是说,TypeScript1.6将得到一个称为的概念。这将更容易捕捉清楚的打字错误(注意,新鲜度仅适用于对象文字):
TS 2.1具有对象扩展和静止功能,因此现在可以:
var my: MyTest = {test: "hello", newTest: "world"}
var { test, ...reduced } = my;
之后,reduced将包含除“test”之外的所有属性。TS 2.1具有对象扩展和Rest,因此现在可以:
var my: MyTest = {test: "hello", newTest: "world"}
var { test, ...reduced } = my;
之后,reduced将包含除“test”之外的所有属性。简单示例:
let all_animals = { cat: 'bob', dog: 'puka', fish: 'blup' };
const { cat, ...another_animals } = all_animals;
console.log(cat); // bob
简单的例子:
let all_animals = { cat: 'bob', dog: 'puka', fish: 'blup' };
const { cat, ...another_animals } = all_animals;
console.log(cat); // bob
这是不可能的。接口的原因是一个Typescript构造,而 因此,在运行时,没有什么可“处理”——没有可查询的属性 @jamesmoey的回答解释了一种实现预期结果的变通方法。 我使用的类似解决方案是将“接口”定义为一个类-
class MyInterface {
test: string = undefined;
}
然后,您可以使用lodash
从“接口”中拾取属性,以注入到对象中:
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
看
这是一个实用的解决方案,它为我提供了很好的服务,没有陷入关于它是否是接口和/或命名约定(例如,
IMyInterface
或MyInterface
)的语义的泥潭,并且允许您模拟和单元测试,这是不可能的。接口的原因是一个Typescript构造,而
因此,在运行时,没有什么可“处理”——没有可查询的属性
@jamesmoey的回答解释了一种实现预期结果的变通方法。
我使用的类似解决方案是将“接口”定义为一个类-
class MyInterface {
test: string = undefined;
}
然后,您可以使用lodash
从“接口”中拾取属性,以注入到对象中:
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
看
这是一个实用的解决方案,对我很有帮助,它没有陷入关于它是否是接口和/或命名约定(例如,
IMyInterface
或MyInterface
)的语义问题,并允许您模拟和单元测试另一种可能的方法:
正如其他答案所提到的,您无法避免在运行时做一些事情;TypeScript编译为JavaScript,主要是通过删除接口/类型定义、注释和断言。类型系统是,在需要的运行时代码中找不到您的MyInterface
var test: MyTest = { test: "hello", newTest: "world" }
const reduced: MyInterface = pick(test, ...myTestKeys);
console.log(JSON.stringify(reduced)); // {"test": "hello"}
class MyClass {
test: string;
public static from(myClass: MyClass): MyClass {
return {test: myClass.test};
}
}
class MyTest extends MyClass {
test: string;
newTest: string;
}
const myTest: MyTest = {test: 'foo', newTest: 'bar'};
const myClass: MyClass = MyClass.from(myTest);