2017-03-26 24 views
3

假设我有这样的类和接口如何使用接口获取对象的子集?

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

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

然后我从什么地方

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

我想用IUser于子集data并删除isAdmin财产这样

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

我的问题是如何在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 
} 

回答

2

有没有办法做到这一点是优于:

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

接口不运行时存在(这是当subset调用),所以你不能使用IUser接口的打字稿知道哪些属性是需要的,哪些不是。

你可以使用一个类做“生存”的编译过程

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

编译为:

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

正如你所看到的,属性不是的一部分编译后的输出,因为类成员只添加到实例而不添加到类中,所以即使是一个类也不会帮助你。

您可以使用修饰符和元数据(more on that here),但这听起来像是您的方案的矫枉过正。

了一个更通用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"' 
相关问题