2017-06-14 59 views
2

假设有一个接口打字稿 - 如何投放对象的接口

interface A { 
    a: number; 
} 

,目前我有一个原始对象

const a = { a: 1, b: '2' }; 

我想到一个办法让x{ a: 1 },其中包含只有界面中定义的成员。

这可以通过创建一个空{}和循环结束,在所有A的成员填补,但考虑接口成员和对象的冗余字段可以高达几十个来实现,这是不实际这样做。

我试图

let x = <A> a; // or let x = a as A; 
console.log((x as any).b); // still exist 

lodash也抬头,发现keyspick,但这些都是针对类的实例,而不是接口。

+2

这不是“铸造”,其不即使在TS存在。这是“挑选”。 – 2017-06-14 06:24:20

+0

@Mike它不清楚你想达到什么。 ** ts **鸭子打字让'a'类型下变换为'A',并且使用打字稿编辑器,您只能访问'A'的成员,但真正的对象始终是'a'类型。因为** ts **类型擦除意味着对象在运行时是'Object'类型,所以您可以看到整个'a'。如果你想__otherother__对象,你必须复制它的属性(如选择解决方案建议)。相反,如果你想编译时检查使用'A',不要担心真实的对象是什么。 – Aris2World

+0

@ Aris2World我有一个接口定义,并希望将具有冗余字段的对象转换为它。另外,我不想明确说明要选择的字段。 – Mike

回答

2

基本上,您的问题归结为将接口的所有属性作为字符串数组获取的问题,然后复制仅包含这些属性的对象。制作对象的副本非常简单,并且有大量的例子。但第一个问题更难解决。

据我所知,完成这个“现在”的唯一方法是在编译期间为打字稿使用自定义转换器。这是一个example,但请注意 - 这需要使用尚未稳定发布的typescript 2.4+。

3

接口在运行时不存在。你最好的选择是自己删除不需要的属性,或者用你需要的属性创建一个对象的副本。

例如,可以使用这样的方法(方法从this answer复制):

function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> { 
    const copy = {} as Pick<T, K>; 

    keys.forEach(key => copy[key] = obj[key]); 

    return copy; 
} 

const a = { a: 1, b: '2' }; 
let copy : A = pick(a, "a"); 
console.log(copy); 
+0

好。如果他想要有一个'A'类型的变量,可以写'let x:A = pick(a,“a”)' – Aris2World

+0

如何提供'''“a”'''?我可以从界面的定义中获得它吗? – Mike

+0

@Mike编号必须来自编译后的值。如果你想得到一个界面的键,你可以看一看Amid提出的[这个库](https://github.com/kimamula/ts-transformer-keys)。但是看这个库的源代码(它读取程序的语法树),可能有点太多了。 – Saravana