如何定义TypeScript类型:输入指定键时允许输入对应关联键
实现TypeScript关联键的类型约束
你需要的是当存在指定键时才允许对应的关联键,原有的联合类型无法实现这个约束——因为联合类型只要满足其中一个分支就会通过,会出现比如同时存在top和offsetLeft这种不符合需求的情况。
可以通过定义多个互斥的类型分支再联合的方式实现需求:
interface Base { top?: number; left?: number; behavior?: "auto" | "smooth" } // 1. 既不使用top/left,也不使用offset相关键的情况 type NoOffsetProps = Pick<Base, Exclude<keyof Base, 'top' | 'left'>> & { top?: never; left?: never; offsetTop?: never; offsetLeft?: never; }; // 2. 使用top时,允许搭配offsetTop,禁止使用left和offsetLeft type WithTopProps = Pick<Base, Exclude<keyof Base, 'left'>> & { top?: number; offsetTop?: number; left?: never; offsetLeft?: never; }; // 3. 使用left时,允许搭配offsetLeft,禁止使用top和offsetTop type WithLeftProps = Pick<Base, Exclude<keyof Base, 'top'>> & { left?: number; offsetLeft?: number; top?: never; offsetTop?: never; }; // 最终的联合类型,覆盖所有合法情况 type FinalProps = NoOffsetProps | WithTopProps | WithLeftProps;
测试示例
// 合法场景 const case1: FinalProps = { behavior: "smooth" }; // 仅基础属性 const case2: FinalProps = { top: 20, offsetTop: 5 }; // top搭配offsetTop const case3: FinalProps = { left: 30, offsetLeft: 10 }; // left搭配offsetLeft const case4: FinalProps = { top: 15 }; // 仅top,无offsetTop const case5: FinalProps = { left: 25 }; // 仅left,无offsetLeft // 非法场景(TypeScript会报错) const invalidCase1: FinalProps = { offsetTop: 5 }; // 单独存在offsetTop,无top const invalidCase2: FinalProps = { top: 20, offsetLeft: 10 }; // top和offsetLeft共存 const invalidCase3: FinalProps = { left: 30, offsetTop: 5 }; // left和offsetTop共存
这个方案通过never类型限制了非法的键组合,确保只有符合需求的键搭配才能通过类型检查。
内容的提问来源于stack exchange,提问作者bazmexes
相关产品推荐
相关产品推荐

