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

TypeScript中如何用接口过滤对象属性?求非类实现方案

TypeScript 用接口过滤对象属性的解决方案

问题背景

假设有如下对象:

const A = {
    id: 123,
    name: "sample",
    foo: "test1",
    bar: "test2"
}

以及定义的接口:

interface I {
     id: number;
     name: string;
}

需要编写函数,过滤对象A得到仅包含接口I属性的新对象:

{
    id: 123,
    name: "sample",
}

尝试keyof特性未生效,求无需类的解决方案。

核心原因

TypeScript的接口是编译时类型,编译后会被完全移除,运行时无法直接获取接口的属性列表。所以单纯用keyof I只能在编译时做类型校验,没法直接用来过滤对象。

解决方案

我们需要同时提供编译时的类型约束和运行时的属性列表,结合两者实现过滤:

1. 定义接口属性的运行时数组

先创建一个包含接口I所有属性名的数组,用as const让TypeScript推断为字面量类型,确保数组内容和接口严格对应:

const iKeys = ['id', 'name'] as const;

2. 编写通用过滤函数

实现一个泛型函数,接收原对象和属性列表,返回仅包含指定属性的新对象,同时保证类型安全:

function pick<T, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K> {
    const result = {} as Pick<T, K>;
    keys.forEach(key => {
        result[key] = obj[key];
    });
    return result;
}

3. 使用函数过滤对象

调用函数时传入对象A和属性数组,得到符合接口I的对象:

const filteredA = pick(A, iKeys);
// 此时filteredA的类型为I,值为{ id: 123, name: "sample" }

进阶:绑定接口I的严格版本

如果想让函数直接和接口I绑定,避免传入错误的属性数组,可以封装一层:

function pickFromI(obj: { [K in keyof I]: unknown }): I {
    return pick(obj, iKeys);
}

const filteredA = pickFromI(A);

这样既保证了运行时的过滤逻辑正确,又通过TypeScript的类型检查确保属性列表和接口完全一致,不会出现漏写或错写属性的情况。

内容的提问来源于stack exchange,提问作者Quasarity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:52:34