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

TypeScript如何用映射类型实现含至少一个原属性且无额外属性的类型

实现方案

你可以通过自定义TypeScript工具类型实现需求,完整代码如下:

// 原类型定义
type A = {
    foo: string;
    bar: number;
    baz: boolean;
}

// 通用工具类型:要求至少包含T的一个属性,且不允许出现T以外的属性,兼容string/number/symbol类型的键
type StrictAtLeastOnePartial<T> = {
    [K in keyof T]: Pick<T, K>
}[keyof T] & Record<Exclude<keyof any, keyof T>, never>

// 最终的B类型
type B = StrictAtLeastOnePartial<A>

校验效果测试

// 编译正常
const b1: B = {
   foo: "yeah"
}
// 多属性同时存在也编译正常
const b11: B = {
    foo: "yeah",
    bar: 123
}

// 报错:空对象不符合要求
const b2: B = {}
// 报错:存在A以外的属性lala
const b3: B = {lala: "lala"}
// 报错:存在A以外的属性but_not_this
const b4: B = {foo: "foo is allowed", but_not_this: false}

实现原理

  1. 至少一个属性约束:{ [K in keyof T]: Pick<T, K> }[keyof T] 会遍历T的所有键,为每个键生成仅包含该键的对象类型,再取所有这些类型的联合。TypeScript的联合类型采用鸭子类型检测,只要对象符合联合中的任意一个分支(即包含至少一个对应属性)就会通过校验,同时也允许多个属性同时存在。
  2. 禁止额外属性约束:Record<Exclude<keyof any, keyof T>, never> 会将所有不属于T的键的类型设为never,一旦赋值了额外属性,TypeScript会检测到属性值和never类型不兼容,直接抛出错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:06:03