使用typescript时,声明的接口可能如下所示:
interface MyInterface {
test: string;
}
具有额外属性的实现可能是这样的:
class MyTest implements MyInterface {
test: string;
newTest: string;
}
示例(此处变量'reduced'仍然包含属性'newTest'):
var test: MyTest = {test: "hello", newTest: "world"}
var reduced: MyInterface = test; // something clever is needed
问题
一般来说,如何使'reduced'变量只包含'MyInterface'接口中声明的属性。
为什么
尝试在将angular.toJson发送到休息服务之前使用'reduced'变量时会出现问题 - toJson方法会转换newTest变量,即使它在编译期间无法在实例上访问,这也会导致休息服务不接受json,因为它有不应该存在的属性。
答案 0 :(得分:5)
这是不可能的。原因是interface
是Typescript构造,而transpiled JS code为空
//this code transpiles to empty!
interface MyInterface {
test: string;
}
因此,在运行时没有什么要“使用”的-没有要询问的属性。
@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
请参阅JSFiddle
这是一个务实的解决方案,对我很有帮助,而又不会陷入有关它实际上是接口和/或命名约定(例如IMyInterface
或MyInterface
)的语义上,并允许您模拟和单元测试
答案 1 :(得分:2)
TS 2.1具有对象传播和休息,因此现在可以:
var my: MyTest = {test: "hello", newTest: "world"}
var { test, ...reduced } = my;
之后,减少将包含除“test”之外的所有属性。
答案 2 :(得分:1)
在您的示例中, newTest 属性无法通过简化变量访问,因此这是使用类型的目标。打字稿带来了类型检查,但它不会操纵对象属性。
答案 3 :(得分:1)
您是否只尝试设置/分配界面上列出的属性?类似的功能在TypeScript中不可用,但编写一个函数来执行您要查找的行为非常简单。
interface IPerson {
name: string;
}
class Person implements IPerson {
name: string = '';
}
class Staff implements IPerson {
name: string = '';
position: string = '';
}
var jimStaff: Staff = {
name: 'Jim',
position: 'Programmer'
};
var jim: Person = new Person();
limitedAssign(jimStaff, jim);
console.log(jim);
function limitedAssign<T,S>(source: T, destination: S): void {
for (var prop in destination) {
if (source[prop] && destination.hasOwnProperty(prop)) {
destination[prop] = source[prop];
}
}
}
&#13;
答案 4 :(得分:0)
一般来说,如何才能减少&#39;变量只包含在&#39; MyInterface&#39;中声明的属性。接口
由于TypeScript是结构,这意味着包含相关信息的任何内容都是Type Compatible,因此是可分配的。
也就是说,TypeScript 1.6将获得一个名为freshness
的概念。这样可以更容易地捕获清晰的拼写错误(注意新鲜度仅适用于对象文字):
// ERROR : `newText` does not exist on `MyInterface`
var reduced: MyInterface = {test: "hello", newTest: "world"};
答案 5 :(得分:0)
简单的例子:
let all_animals = { cat: 'bob', dog: 'puka', fish: 'blup' };
const { cat, ...another_animals } = all_animals;
console.log(cat); // bob
答案 6 :(得分:0)
一种解决方案可能是使用 class
而不是 interface
并使用 factory method
(返回其类型的新对象的公共静态成员函数)。模型是您知道允许的属性的唯一地方,也是您不会忘记在模型更改时意外更新它们的地方。
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);
答案 7 :(得分:-4)
可能是以下的副本:
TypeScript or JavaScript type casting
您必须将您的值“转换”为其他类型。
一些很好的例子也在这里:http://blogs.microsoft.co.il/gilf/2013/01/18/using-casting-in-typescript/
this.span = <HTMLSpanElement>document.createElement('span');
希望这有帮助吗?