You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:40:36