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

如何在TypeScript中类型安全地将符合接口A的对象转换为符合接口B的对象?

如何在TypeScript中类型安全地将符合接口A的对象转换为符合接口B的对象?

这确实是TypeScript开发里常见的小痛点,我来给你几个完全类型安全的解决方案,既能满足类型检查要求,又不会留下多余属性或者undefined值~

首先先明确你的接口定义:

interface A {
  foo: string;
  bar: number;
}

interface B {
  foo: string;
}

方案一:手动解构提取目标属性

最简单直接的方式,明确提取你需要的foo属性,生成的对象完全符合B类型,也不会包含多余的bar:

const a = { foo: "baz", bar: 42 };

// 写法1:直接赋值
const b: B = { foo: a.foo };

// 写法2:解构更简洁
const { foo } = a;
const b: B = { foo };

这种方法最直观,完全通过TypeScript的类型检查,生成的b对象也确实只有foo属性,完美适配Firestore这类不接受undefined属性的场景。

方案二:封装可复用的类型安全工具函数

如果需要多次进行这类转换,或者目标接口的属性较多,可以写一个通用的pick函数,利用TypeScript的泛型和Pick工具类型来保证类型安全:

// 泛型函数:提取对象中指定的属性,返回对应类型
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
}

// 使用示例
const a = { foo: "baz", bar: 42 };
const b: B = pick(a, 'foo');

这里的Pick<A, 'foo'>类型和你的B接口完全等价,所以赋值给b时不会有类型问题,而且函数确保我们只能提取原对象存在的属性,避免手动写错属性名。

方案三:通过属性过滤生成新对象

如果目标接口的属性较多,不想一个个手动提取,可以通过过滤对象键值对来生成符合要求的对象:

const a = { foo: "baz", bar: 42 };
// 定义允许的属性列表(和B接口的键对应)
const allowedKeys: (keyof B)[] = ['foo'];

const b: B = Object.fromEntries(
  Object.entries(a).filter(([key]) => allowedKeys.includes(key as keyof B))
) as B;

这里的类型断言as B是安全的,因为我们明确只保留了B接口中定义的属性,生成的对象不会有多余的bar,也不会出现undefined值。

为什么你之前的方法不行?

  • 直接delete b.bar报错:因为TypeScript认为b是B类型,不存在bar属性,所以编译器会阻止这个操作;
  • 赋值bar: undefined:虽然类型上符合,但实际对象中会保留bar: undefined这个键值对,这会导致像Firestore这类工具拒绝接收,不符合你的需求;
  • 使用any:确实能绕开类型检查,但完全失去了TypeScript的类型安全保障,不推荐。

备注:内容来源于stack exchange,提问作者Jonas Sourlier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 15:32:35