TypeScript中如何根据同一对象的另一个Key为指定Key设置条件类型
解决方案
你需要将Props定义为可辨识联合类型,即可实现基于status判断自动收窄log类型的效果,代码如下:
enum StatusEnum { UPDATE = 'update', CREATE = 'create' } // 定义可辨识联合类型 type Props = | { status: StatusEnum.UPDATE log: Record<string, any> // 此处可添加UPDATE场景下特有的属性 } | { status: StatusEnum.CREATE log: undefined // 此处可添加CREATE场景下特有的属性 }
如果存在多个和status无关的公共属性,可以抽取公共部分避免重复编写:
// 公共属性定义 type CommonProps = { id: number title: string // 其他所有场景通用的属性... } type Props = CommonProps & ( | { status: StatusEnum.UPDATE, log: Record<string, any> } | { status: StatusEnum.CREATE, log: undefined } )
原写法报错原因
- 第一种非泛型写法中,
LogKeyType<status>里的status是Props的属性值,不属于类型范畴,而TypeScript泛型参数要求传入类型,因此直接抛出「值被作为类型使用」的报错。 - 第二种泛型写法的问题在于,当你使用
Props时如果未显式指定泛型参数、或泛型参数被推导为联合类型StatusEnum时,TypeScript无法通过status的判断自动收窄泛型对应的log类型,泛型的类型收窄逻辑和固定联合类型的收窄逻辑不通用。
使用示例
按上述方案定义后,你的场景可以直接正常运行,不需要额外判断log是否为undefined:
function test(props: Props) { if (props.status === StatusEnum.UPDATE) { // 此处log自动识别为Record<string, any>类型,可直接访问属性 console.log(props.log.xxx) } else { // 此处log自动识别为undefined类型 console.log(props.log) } }
内容的提问来源于stack exchange,提问作者HartWoom
相关产品推荐
相关产品推荐

