TypeScript Discriminated Union报错:属性在类型上不存在(Reducer场景)
解决Reducer中Discriminated Union类型的payload属性不存在错误
问题原因
提前执行const { type, payload } = action解构后,TypeScript无法再关联type与payload的类型绑定关系——二者成为独立变量后,payload始终是两个action payload的联合类型,导致在case分支中访问专属属性时触发类型检查错误。
解决方案
方案1:避免提前解构(推荐)
直接在switch分支中使用action.type和action.payload,让TypeScript自动收窄每个分支的payload具体类型:
interface AuthenticatedUserState { user?: any isAdmin?: boolean isRegistered?: boolean err?: any isError?: boolean isSignedOut?: boolean authorizationData?: any } const INITIAL_STATE: AuthenticatedUserState = { user: null, isError: false, err: null, isSignedOut: false } interface AUTHENTICATED_USER_ACTION { type: 'authentication/AUTHENTICATED_USER' payload: { authenticatedUser: any isAdmin: boolean } } interface REGISTER_USER_ACTION { type: 'authentication/REGISTER_USER' payload: { isRegistered: boolean err: any } } const AUTHENTICATED_USER = 'authentication/AUTHENTICATED_USER' const REGISTER_USER = 'authentication/REGISTER_USER' type ACTION = AUTHENTICATED_USER_ACTION | REGISTER_USER_ACTION const authenticatedUserReducer = ( state: AuthenticatedUserState = INITIAL_STATE, action: ACTION ): AuthenticatedUserState => { switch (action.type) { case AUTHENTICATED_USER: return { ...state, user: action.payload.authenticatedUser, isAdmin: action.payload.isAdmin } case REGISTER_USER: return { ...state, isRegistered: action.payload.isRegistered, err: action.payload.err } default: return state } }
方案2:使用类型断言(按需选择)
如果业务场景必须提前解构,可以在每个case分支中给payload做类型断言,明确当前分支的payload类型:
const authenticatedUserReducer = ( state: AuthenticatedUserState = INITIAL_STATE, action: ACTION ): AuthenticatedUserState => { const { type, payload } = action switch (type) { case AUTHENTICATED_USER: const authPayload = payload as AUTHENTICATED_USER_ACTION['payload'] return { ...state, user: authPayload.authenticatedUser, isAdmin: authPayload.isAdmin } case REGISTER_USER: const registerPayload = payload as REGISTER_USER_ACTION['payload'] return { ...state, isRegistered: registerPayload.isRegistered, err: registerPayload.err } default: return state } }
内容的提问来源于stack exchange,提问作者LogiStack
相关产品推荐
相关产品推荐

