簡體   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