gpt4 book ai didi

typescript - 当 TypeScript 中有多种可能的类型时,如何指示返回类型是什么?

转载 作者:搜寻专家 更新时间:2023-10-30 21:44:50 25 4
gpt4 key购买 nike

我正在尝试围绕 Axios API 客户端编写类型,但不了解告诉编译器我期望的返回类型的正确方法。

一个简化的例子:

import axios, { AxiosResponse } from "axios";

interface BaseApiResponse extends AxiosResponse { }

interface ApiCollectionResponse<T> extends BaseApiResponse {
data: T[]
meta: {
totalCount: number
totalPages: number
}
}

interface ApiResourceResponse<T> extends BaseApiResponse {
data: T
}

type ApiResponse<T> = ApiCollectionResponse<T> | ApiResourceResponse<T>

const apiAction = <T>(url: string, onSuccess: (response: ApiResponse<T>) => void) => {
axios
.request({ url })
.then(({ data }) => {
onSuccess(data)
})
}

interface User {
name: string
}

const loadUsers = () =>
apiAction<User>('/users', (data) => alert(data.meta.totalCount))

响应数据可以是 ApiCollectionResponseApiResourceResponse。编译器正确地提示属性 metaApiResourceResponse 接口(interface)上不存在。

我如何表达对 apiAction 的调用将导致 ApiCollectionResponse 返回值?

最佳答案

只要所有内容都封装在同一个 API/axios 模块中,在何处对获取的数据进行类型转换应该无关紧要。对于消费模块,只有 loadUsers 或其他导出方法很重要。

您可以执行以下操作之一:

1.) 定义显式方法 apiActionUsersapiActionXXX 等(最简单,如果你问我的话):

function apiActionUsers() {
apiAction<User>("/users", data =>
alert((data as ApiCollectionResponse<User>).meta.totalCount)
)
}

除了原始转换,您还可以定义一个 type guard而不是区分 ApiResponse 的可能类型。

2.) 使用function overloards :

type ApiAction = {
<T>(
url: "/users",
onSuccess: (response: ApiCollectionResponse<T>) => void
): void
<T>(
url: "/other-resource",
onSuccess: (response: ApiResourceResponse<T>) => void
): void
}

const apiAction: ApiAction = (
url: string,
onSuccess: (response: any) => void
) => {
axios.request({ url }).then(onSuccess)
}

// works!
apiAction<User>("/users", data => alert(data.meta.totalCount))

看看here对于具有函数重载的示例。

关于typescript - 当 TypeScript 中有多种可能的类型时,如何指示返回类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57349793/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com