如何在TypeScript中为接口编写条件布尔类型?
React组件Props的条件布尔类型实现方案
需求明确:当editable为true时,必须传入类型为Sheets.Matrix的position;当editable为false时,position不能传入。你之前的写法无法让TypeScript关联editable和position的依赖关系,得用联合类型实现这种属性间的条件约束。
正确实现方式
方式1:直接定义联合接口
把Props拆成两种状态的接口,再组合成联合类型:
type Props = | { editable: true; position: Sheets.Matrix; value: string; classNames?: string; textType?: "bold" | "editing" | "normal"; onChange?: (val: Sheets.SaveData) => void; } | { editable: false; position?: never; // 用never严格禁止传入position value: string; classNames?: string; textType?: "bold" | "editing" | "normal"; onChange?: (val: Sheets.SaveData) => void; };
方式2:提取公共属性(推荐)
把两种状态下的公共属性抽出来,减少重复代码:
// 先定义所有状态共用的属性 type CommonProps = { value: string; classNames?: string; textType?: "bold" | "editing" | "normal"; onChange?: (val: Sheets.SaveData) => void; }; // 再组合成联合类型 type Props = | (CommonProps & { editable: true; position: Sheets.Matrix; }) | (CommonProps & { editable: false; position?: never; });
组件内使用注意事项
因为是联合类型,在组件内部访问position时,需要通过editable的值做类型收窄,TypeScript才会自动推断position的类型:
const SheetsCell: React.FC<Props> = ({ editable, value, textType = "normal", classNames = "", position, }) => { if (editable) { // 这里position的类型被确定为Sheets.Matrix,可以直接使用 console.log(position.row, position.col); } // 其他逻辑... };
这样实现后,组件使用时会得到严格约束:
- 传
editable={true}时,TypeScript强制要求传入position; - 传
editable={false}时,TypeScript会报错阻止传入position,完全匹配需求。
内容的提问来源于stack exchange,提问作者Alwaysblue
相关产品推荐
相关产品推荐

