TypeScript - 仅提取接口成员 - 可能吗? [英] TypeScript - extract interface members only - possible?
问题描述
有没有办法从属于接口的对象中动态提取成员(即不再次明确指定它们),如下所示:
Is there a way to dynamically extract members from an object belonging to an interface (i.e. not specifying them again explicitly), like this:
let subset = { ...someObject as ISpecific };
目前我得到 someObject 碰巧拥有的所有成员.所以传播运算符在这里不起作用.有没有办法做到这一点?
Currently I get all members that someObject happens to have. So the spread operator does not work here. Are there any ways to do that yet?
示例:
interface ISpecific { A: string; B: string; }
class Extended implements ISpecific { public A: string = '1'; public B: string = '2'; public C: string = '3'; }
let someObject = new Extended();
let subset = { ...someObject as ISpecific };
console.log(subset); // -> { A, B, C } but want { A, B }
TypeScript 类型转换只是编译器的提示,而不是运行时的真正转换.
TypeScript casts are merely hints for the compiler, not real conversions at runtime.
推荐答案
可以使用装饰器来实现(见文末要求).它只能与方法一起使用(复制属性 get/set 访问器只会产生其瞬时返回值,而不是访问器函数).
// define a decorator (@publish) for marking members of a class for export:
function publish(targetObj: object, memberKey: string, descriptor: PropertyDescriptor) {
if (!targetObj['_publishedMembers'])
targetObj['_publishedMembers'] = [];
targetObj['_publishedMembers'].push(memberKey);
}
// this function can return the set of members of an object marked with the @publish decorator:
function getPublishedMembers(fromObj: object) {
const res = {};
const members = fromObj['_publishedMembers'] || [];
members.forEach(member => { res[member] = fromObj[member].bind(fromObj); });
return res;
}
// this is for making sure all members are implemented (does not make sure about being marked though):
interface IPublishedMembers {
A(): string;
B(): number;
C(): void;
}
// this class implements the interface and has more members (that we do NOT want to expose):
class Full implements IPublishedMembers {
private b: number = 0xb;
@publish public A(): string { return 'a'; }
@publish public B(): number { return this.b; }
@publish public C(): boolean { return true; }
public D(): boolean { return !this.C(); }
public E(): void { }
}
const full = new Full();
console.log(full); // -> all members would be exposed { A(), B(), b, C(), D(), E() }
const published = getPublishedMembers(full) as IPublishedMembers;
console.log(published); // -> only sanctioned members { A(), B(), C() }
console.log(published.B()); // -> 11 = 0xb (access to field of original object works)
(这需要 tsconfig.json 中的 compilerOption "experimentalDecorators":true 和 ES5 目标,更多信息请参见 http://www.typescriptlang.org/docs/handbook/decorators.html)
这篇关于TypeScript - 仅提取接口成员 - 可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!