TypeScript如何无需自定义方法提取类的公开属性为JSON对象?
TypeScript提取类公开属性的简便方法
问题描述
请问在TypeScript中,除了在类中编写自定义方法返回类变量对象外,是否有更简便或内置的方式,仅提取类的公开属性(排除方法与私有属性)为对象?是否可以直接通过const TableVariablesAsObject = TablesArray[1]的方式得到类似PokerObject的对象,而非调用TablesArray[1].getAsObject()?
相关代码示例
interface PokerObject { smallBlind: number; bigBlind: number; size: number; } interface PokerTable { smallBlind: number; bigBlind: number; size: number; GetNextPlayer: (extra: number) => number; getAsObject: () => PokerObject; } class Poker_Table implements PokerTable { public smallBlind: number; public size: number; public bigBlind: number; private id: string; constructor(id: string, size: number, smallBlind: number, bigBlind: number) { this.id = id; this.smallBlind = smallBlind; this.bigBlind = bigBlind; this.size = size; } getAsObject(): PokerObject { return { smallBlind: this.smallBlind, size: this.size, bigBlind: this.bigBlind, }; } GetNextPlayer(extra: number): number { // return sum number return 1; } }
类实例存入数组的代码
const Table1: PokerTable = new Poker_Table("1", 2, 1, 1); const Table2: PokerTable = new Poker_Table("1", 2, 1, 1); const Table3: PokerTable = new Poker_Table("1", 2, 1, 1); const TablesArray: Array<PokerTable> = [Table1, Table2, Table3];
解答
1. 直接赋值无法得到目标对象
你不能直接通过const TableVariablesAsObject = TablesArray[1]得到PokerObject类型的对象。因为TablesArray[1]是Poker_Table的实例,它包含了GetNextPlayer、getAsObject方法以及私有属性id(运行时仍存在,仅类型层面隐藏),类型和结构都不符合PokerObject的定义。
2. 更简便的提取方式
方式一:解构赋值+类型断言
如果属性数量不多,直接解构需要的公开属性,再通过类型断言匹配目标类型,写法直观简洁:
const { smallBlind, bigBlind, size } = TablesArray[1]; const TableVariablesAsObject = { smallBlind, bigBlind, size } as PokerObject;
方式二:通用工具函数复用
如果需要多次提取相同类型的属性,可以封装一个通用函数,指定要提取的属性列表,避免重复代码:
function extractPublicProps<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { return keys.reduce((acc, key) => { acc[key] = obj[key]; return acc; }, {} as Pick<T, K>); } // 使用示例 const TableVariablesAsObject = extractPublicProps(TablesArray[1], ['smallBlind', 'bigBlind', 'size']) as PokerObject;
如果想自动过滤方法和私有字段(ES私有字段以#开头),可以写另一个版本的工具函数,但注意这种方式可能误判getter等特殊属性,适合属性明确的场景:
function extractNonMethodPublicProps<T>(obj: T): Partial<T> { const result: Partial<T> = {}; for (const key in obj) { // 排除私有字段和方法类型的属性 if (!key.startsWith('#') && typeof obj[key] !== 'function') { result[key as keyof T] = obj[key]; } } return result; } // 使用示例 const TableVariablesAsObject = extractNonMethodPublicProps(TablesArray[1]) as PokerObject;
方式三:利用toJSON方法(序列化场景)
如果需要将实例序列化为JSON时自动返回目标结构,可以在类中实现toJSON方法,这样用JSON.stringify处理时会自动生成符合要求的对象:
class Poker_Table implements PokerTable { // ... 原有代码 toJSON(): PokerObject { return { smallBlind: this.smallBlind, size: this.size, bigBlind: this.bigBlind, }; } } // 使用示例 const TableVariablesAsObject = JSON.parse(JSON.stringify(TablesArray[1])) as PokerObject;
这种方式适合需要序列化的场景,但存在JSON序列化的性能开销。
内容的提问来源于stack exchange,提问作者Abd
相关产品推荐
相关产品推荐

