TypeScript - 仅提取接口成员 - 可能吗? [英] TypeScript - extract interface members only - possible?

查看:18
本文介绍了TypeScript - 仅提取接口成员 - 可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法从属于接口的对象中动态提取成员(即不再次明确指定它们),如下所示:

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屋!

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