如何使用接口获取对象的子集? [英] How to take a subset of an object using an interface?
问题描述
假设我有此类和接口
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屋!