How to take a subset of an object using an interface?

…衆ロ難τιáo~ 提交于 2020-01-03 18:38:10

问题


Suppose I have this class and interface

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

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

And then I get this json object from somewhere

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

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

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
}

回答1:


There's no way to do that which is better than:

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

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;
}

Compiles to:

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.

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

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"'


来源:https://stackoverflow.com/questions/43028324/how-to-take-a-subset-of-an-object-using-an-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!