【问题标题】:Typescript - How to cast object to interfaceTypescript - 如何将对象转换为接口
【发布时间】:2017-06-14 05:51:05
【问题描述】:

假设有一个接口

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,但这些都是针对类实例而不是接口的。

【问题讨论】:

  • 这不是“铸造”,它甚至在 TS 中都不存在。这是“采摘”。
  • @Mike 不清楚你想要实现什么。 ts 鸭子打字让a 的类型向下转换为A,并且使用打字稿编辑器,您只能访问A 的成员,但真实对象始终是a 类型。因为 ts 类型擦除意味着对象在运行时属于 Object 类型,所以您会看到整个 a。如果您想要 another 对象,则必须复制其属性(如选择解决方案建议的那样)。相反,如果您想要编译时检查,请使用 A 并且不要担心真正的对象是什么。
  • @Aris2World 我有一个接口定义,想将一个带有冗余字段的对象转换为它。另外,我不想明确说明要选择的字段。
  • @Mike 可能对对象和类型(接口代表什么)存在误解。假设你也有这个interface B { b: string; }。您可以将对象a 视为AB 类型的对象:let x: A = a 您可以访问Alet x: B = a 的成员您可以访问B 的成员。对象a 是Object 类型,它是javascript 中唯一存在的对象。

标签: typescript


【解决方案1】:

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

例如你可以使用这样的方法(从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);

【讨论】:

  • 好。仅补充一点,如果他想拥有A 类型的变量,他可以写let x: A = pick(a, "a")
  • 如何提供"a"?我可以从接口的定义中得到它吗?
  • @Mike 否。它必须来自编译后存在的值。如果你想获取某个接口的key,可以看看Amid 推荐的this library。但是看那个库的源码(它读取程序的语法树),可能有点过头了。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2017-10-09
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 2021-07-28
    • 2011-05-07
    相关资源
    最近更新 更多