【问题标题】:Working with Typescript Interfaces- error: property does not exist使用 Typescript 接口 - 错误:属性不存在
【发布时间】:2021-09-01 12:33:53
【问题描述】:

我建立了这个界面

export interface UserInfo {
    success?: boolean,
    user?: User,
    employer?: Employer,
    hr?: Hr
}

现在当我这样做时

let data = await loginUser(loginData);
console.log(data.success);

loginUser方法代码:

import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
import {BASE_API_ENDPOINT, LOGIN_API_ENDPOINT} from "../../constants/apis";
import {LoginData, UserInfo} from "../../models/apis/UserData";

export const loginApi = createApi({
    reducerPath: 'loginReducer',
    baseQuery: fetchBaseQuery({ baseUrl: BASE_API_ENDPOINT }),
    endpoints: (builder) => ({
        loginUser: builder.mutation<UserInfo, LoginData> ({
            query: (data: LoginData) => ({
                    url: LOGIN_API_ENDPOINT,
                    method: "POST",
                    body: data
            }),
            transformResponse: (rawResult : UserInfo) => {
                return rawResult
            }
        })
    })
})
export const { useLoginUserMutation } = loginApi;

我收到此错误

类型'{ data: UserInfo; 上不存在属性'success'; } | { 错误:FetchBaseQueryError |序列化错误; }'。

我是打字稿的新手,我想从 { data: UserInfo; 访问 UserInfo 对象但我不能这样做。有人可以帮忙吗?

【问题讨论】:

  • 这看起来像是一个错误的方法输入。能否也给我们看看loginUser()的代码?
  • loginUser api 是否返回 { data: UserInfo; } 作为响应?
  • 我在描述中添加了 loginUser 方法
  • 该错误表明您正在使用的数据可能不是成功的结果。在这种情况下,您需要使用类型保护来缩小类型。
  • Console.log 您的回复或在邮递员上查看您收到的回复

标签: javascript reactjs typescript redux redux-toolkit


【解决方案1】:

发生这种情况是因为“成功”属性仅存在于 UserInfo 类型上。 由于它是联合类型,编译器无法确定函数返回的是数据对象(UserInfo 类型)还是错误对象(FetchBaseQueryError | SerializedError)

为了访问响应的成功属性,你可以先检查它是否存在

if("success" in data){
    console.log(data.success)
}

在此处阅读有关联合类型的更多信息:
https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types

【讨论】:

  • 我很确定在这里你只是强制data 被编译器视为UserInfo(或者更确切地说是具有success 字段的类型)。但是,如果您真的进行测试,您会看到transformResponse 接收到一个包装实际 UserInfo 对象的对象。在此处阅读有关 createApi 突变/transformResponse 的更多信息:redux-toolkit.js.org/rtk-query/usage/mutations
  • 首先,我添加答案的时候没有transform response/createapi,只有接口和异步调用。而且我很确定这不是强迫的,因为它是之前的检查:)。强制将使用类似:(data as UserInfo).success
  • 对不起。我的意思是“强制” TS 编译器将其视为包含该字段的类型。我说的不是真正的演员阵容。然而,底线是数据很可能是 { data: UserInfo } 类型,如 OP 错误所述。
  • 进行此检查实际上对我有用!谢谢
【解决方案2】:

实际问题在 transformResponse 函数中发现,以及它如何进一步“隧道”响应数据。

transformResponse: (rawResult : UserInfo) => {
  return rawResult
}

rawResult 很可能不是UserInfo 类型,而是{ data: UserInfo }。这正是您在收到的错误中看到的内容。

所以要修复它,函数应该如下所示:

transformResponse: (rawResult: { data: UserInfo }) => {
  return rawResult.data
}

然后您的代码应该按预期工作,没有任何其他ifs。

let data = await loginUser(loginData);
console.log(data.success);

【讨论】:

  • 我猜这里的问题不在运行时,而是打字稿抱怨类型不匹配。而且我认为这是一个类型问题,工具包无法告诉 IDE transformResponse 可以转换类型
  • 很可能不是,因为正如我上面所说,rawResult 不是UserInfo 类型,而是{ data: UserInfo } 类型。所以这就是为什么我们需要正确输入函数参数然后返回rawResponse.data。通过这样做,静态类型检查也应该得到整理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 2016-06-22
  • 2018-10-13
  • 2023-02-21
相关资源
最近更新 更多