How do I take a subset of an object using an interface?

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 multiply data

with IUser

and remove a property isAdmin

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 this functionality 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
}

      

+3


source to share


1 answer


There is no way to do anything better than:

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

      

Typescript interfaces do not exist at runtime (i.e. when called subset

), so you cannot use an interface IUser

to find out which properties are needed and which are not.

You can use a class that survives the compilation process , but :

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

      

It will compile:



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

      

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

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

Another option for a more general function subset

:

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

      

+2


source







All Articles