繁体   English   中英

Typescript 受歧视的联合:类型上不存在属性

[英]Typescript discriminated unions: Property does not exist on type

我将为 Reducer Action 使用 Discriminated Union 类型。

但是当我使用它时,编译器说有效负载不包含该属性。

代码看起来像


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 => {
    const { type, payload } = action
    switch (type) {
        case AUTHENTICATED_USER:
            return {
                ...state,
                user: payload.authenticatedUser,
                isAdmin: payload.isAdmin
            }
        case REGISTER_USER:
            return {
                ...state,
                isRegistered: payload.isRegistered,
                err: payload.err
            }
        default:
            return state
    }
}

然后,错误是

Property 'err' does not exist on type '{ authenticatedUser: any; isAdmin: boolean; } | { isRegistered: boolean; err: any; }'.
  Property 'err' does not exist on type '{ authenticatedUser: any; isAdmin: boolean; }'.

您可以通过升级 TypeScript 版本来修复错误。 使用 v4.9.4 查看游乐场: 游乐场

看起来您可能正在使用 typescript 版本 < 4.6。

在 TS < 4.6 的情况下,当您解构具有可区分联合类型的值时:

const { type, payload } = action

您正在创建两个彼此没有联系的新变量,也没有从中解构它们的项目。 编译器无法通过检查type来缩小payloadaction的范围。

此行为在typescript > 4.6中发生变化,因此应考虑升级您的 typescript 版本。

否则,在 TS4.6 之前的世界中,不要出于类型缩小/控制流的目的从您的已区分联合中解构项目。

switch (action.type) {
    case AUTHENTICATED_USER:
        return {
            ...state,
            user: action.payload.authenticatedUser,
            isAdmin: action.payload.isAdmin
        }
    // ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM