如何使用接口获取对象的子集? [英] How to take a subset of an object using an interface?

查看:120
本文介绍了如何使用接口获取对象的子集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有此类和接口

class User {
    name: string;
    age: number;
    isAdmin: boolean;
}

interface IUser {
    name: string;
    age: number;
}

然后我从某个地方得到这个json对象

And then I get this json object from somewhere

const data = {
    name: "John",
    age: 25,
    isAdmin: true
}

我想使用IUser子集data并删除这样的isAdmin属性

I want to subset data using IUser and remove the isAdmin property like this

let user = subset<IUser>(data);
// user is now { name: "John", age: 25 }
// can safely insert user in the db

我的问题是如何在TypeScript中实现该功能?

My question is how do I implement that function in TypeScript?

function subset<T>(obj: object) {
    // keep all properties of obj that are in T
    // keep, all optional properties in T
    // remove any properties out of T
}

推荐答案

没有比这更好的方法了

function subset(obj: IUser) {
    return {
        name: obj.name,
        age: obj.age
    }
}

在运行时(调用subset时),typescript接口不存在,因此您不能使用IUser接口来了解哪些属性是必需的.

The typescript interfaces don't exist at runtime (which is when subset is invoked) so you cannot use the IUser interface to know which properties are needed and which aren't.

您可以使用可以存活"编译过程的类,但是:

You can use a class which does "survive" the compilation process but:

class IUser {
    name: string;
    age: number;
}

编译为:

var IUser = (function () {
    function IUser() {
    }
    return IUser;
}());

如您所见,属性不是已编译输出的一部分,因为类成员仅添加到实例而不是类,因此即使类也无法为您提供帮助.

As you can see, the properties aren't part of the compiled output, as the class members are only added to the instance and not to the class, so even a class won't help you.

您可以使用装饰器和元数据(更多有关此处的信息 ),但这听起来像是您的方案的矫kill过正.

You can use decorator and metadata (more on that here) but that sounds like an overkill for your scenario.

更通用的subset函数的另一个选项是:

Another option for a more generic subset function is:

function subset<T>(obj: T, ...keys: (keyof T)[]) {
    const result = {} as T;

    keys.forEach(key => result[key] = obj[key]);
    return result;
}
let user1 = subset(data, "name", "age");
let user2 = subset(data, "name", "ag"); // error: Argument of type '"ag"' is not assignable to parameter of type '"name" | "age" | "isAdmin"'

这篇关于如何使用接口获取对象的子集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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