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

如何基于接口与对象,用泛型生成指定可选键转必填的新类型?

解决方法

要实现“将接口中存在于具体对象的可选键转为必填,其余键保持原有状态”的需求,核心是让TypeScript捕获对象实际存在的键,而非仅依赖接口的类型定义。

问题根源

你当前代码里,const person: personInterface = { ... } 强制把对象类型约束为personInterface,导致typeof person返回的是接口的完整类型,而非对象字面量的实际键集合。因此keyof typeof person会包含接口所有键(id/name/title),最终把所有属性都设为必填,不符合预期。

正确实现步骤

1. 改进工具类型

编写泛型类型,接受接口T和对象的实际类型U(需满足U extends T),提取U中的键并将其在T中转为必填:

type MakeRequiredFromObj<T, U extends T> = Omit<T, keyof U> & {
    [P in keyof U]-?: T[P];
};

2. 保留对象的实际类型

使用satisfies关键字(TypeScript 4.9+)确保对象符合接口约束的同时,保留其字面量的具体类型:

interface personInterface {
    id?: number;
    name?: string;
    title?: string;
}

// 用satisfies确保对象符合接口,但保留实际键的类型
const person = {
    id: 2,
    name: "John",
} satisfies personInterface;

若你的TypeScript版本低于4.9,可通过交叉类型手动约束:

const person: personInterface & { id: number; name: string } = {
    id: 2,
    name: "John",
};

3. 生成目标类型

现在可以生成符合需求的新类型:

type OptionalToRequiredData = MakeRequiredFromObj<personInterface, typeof person>;

// 验证:id和name为必填,title仍为可选
const resultPerson: OptionalToRequiredData = {
    id: 2,
    name: 'John',
    // title可省略,或按需赋值
};

额外:工具函数简化推导

如果不想手动传递泛型参数,可写一个工具函数自动推导类型:

function createRequiredType<T>() {
    return function <U extends T>(obj: U): MakeRequiredFromObj<T, U> {
        return obj as MakeRequiredFromObj<T, U>;
    };
}

// 使用方式
const resultPerson = createRequiredType<personInterface>()(person);

内容的提问来源于stack exchange,提问作者Николай Шляпников

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:00:52