如何在TypeScript中复用类型实现二选一属性的联合类型?
TypeScript 复用基础属性实现联合类型的正确写法
现有基础接口:
interface BaseProps { value: string somethingElse?: boolean }
需要实现一个联合类型,无需重复编写基础属性,等价于以下代码:
interface PropsOne { value: string somethingElse?: boolean onChange: (s: string) => void } interface PropsTwo { value: string somethingElse?: boolean onAccept: (s: string) => void } type Props = PropsOne | PropsTwo
问题分析
你尝试的交叉+联合写法会导致语言服务器无法正确识别必选属性:
type Props = { value: string somethingElse?: boolean } & ({ onAccept: (s: string) => void } | { onChange: (s: string) => void })
这是因为TS会将onAccept和onChange都解析为可选属性(联合类型的成员可能只包含其中一个),所以无法准确推断每个分支的必选字段。
正确实现方式
方式一:接口继承(最直观)
通过extends让子接口继承基础属性,再组合成联合类型:
interface BaseProps { value: string somethingElse?: boolean } interface PropsOne extends BaseProps { onChange: (s: string) => void } interface PropsTwo extends BaseProps { onAccept: (s: string) => void } type Props = PropsOne | PropsTwo
方式二:直接交叉每个联合成员
如果不想额外定义子接口,可以将基础类型分别与每个扩展属性交叉,再组成联合类型:
interface BaseProps { value: string somethingElse?: boolean } type Props = (BaseProps & { onChange: (s: string) => void }) | (BaseProps & { onAccept: (s: string) => void })
这两种写法都能让TS准确识别每个分支的必选属性,语言服务器也会正常给出代码提示。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

