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

如何约束TypeScript函数仅接受兼容空对象的类型?

TypeScript 约束泛型仅接受兼容空对象的类型

问题场景

以下代码可正常运行,空对象能被赋值给Data类型:

export type Data = Record<string, unknown> 

const x: Data = {}

但在泛型函数中,直接给泛型变量赋值空对象会触发类型错误:

export const createManager = <FormData extends Data>(
    initial: FormData,
) => {
    const x: FormData = {}; // TypeScript 报错
}

报错信息:

'{}' is assignable to the constraint of type 'FormData', but 'FormData' could be instantiated with a different subtype of constraint 'Data'.(2322)

问题核心:FormData可能被推断为Data的子类型(比如{ name: string }),这类子类型包含必填属性,空对象无法兼容。需要约束函数仅接受空对象可赋值的FormData类型。

解决方案

方案一:通过条件约束泛型参数

在泛型约束中加入条件判断,筛选出满足{} extends FormData的类型:

export type Data = Record<string, unknown>;

export const createManager = <FormData extends ({} extends FormData ? Data : never)>(
    initial: FormData,
) => {
    const x: FormData = {}; // 不再报错
};

// 测试用例
createManager({}); // 正常通过
createManager({ name: "test" }); // 报错,符合预期({} 无法赋值给 { name: string })

原理:利用条件类型过滤出兼容空对象的类型,不符合条件的会被约束为never,调用时直接触发类型错误。

方案二:使用Partial<Data>作为泛型约束

如果业务场景允许FormData仅包含可选属性,可直接将泛型约束改为Partial<Data>:

export type Data = Record<string, unknown>;
export type PartialData = Partial<Data>;

export const createManager = <FormData extends PartialData>(
    initial: FormData,
) => {
    const x: FormData = {}; // 不再报错
};

// 测试用例
createManager({}); // 正常通过
createManager({ name?: "test" }); // 正常通过
createManager({ name: "test" }); // 报错,符合预期

原理:Partial<Data>会将Data的所有属性转为可选类型,此时空对象能兼容所有该类型的子类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:20:59