如何使用接口获取对象的子集?
Posted
技术标签:
【中文标题】如何使用接口获取对象的子集?【英文标题】:How to take a subset of an object using an interface? 【发布时间】:2017-08-19 02:14:20 【问题描述】:假设我有这个类和接口
class User
name: string;
age: number;
isAdmin: boolean;
interface IUser
name: string;
age: number;
然后我从某个地方得到这个 json 对象
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
我的问题是如何在 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】:没有比这更好的方法了:
function subset(obj: IUser)
return
name: obj.name,
age: obj.age
typescript 接口在运行时不存在(即调用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"'
【讨论】:
以上是关于如何使用接口获取对象的子集?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Firebase Firestore 获取子集合? [复制]
如何使用 react-redux-firebase 从 firestore 获取子集合