typescript - 根据打字稿中的字符串文字缩小类型?
问题描述
我想输入一个 api 响应,其中资源在资源名称键上返回,即{ [resourceName]: resources, total: 10 }
. 在以下示例中,根据请求的内容,我将如何键入响应对象来表示响应中存在apples
或存在:oranges
interface Response {
total: number
apples: Array<object>
oranges: Array<object>
}
const get = async (fruit: 'apples' | 'oranges') => {
const data: Response = await fetchFruit(`https://example.com/${fruit}`)
const count = data.total
const applesOrOranges = data[fruit].filter(Boolean)
}
我想我必须对不同的可能响应使用联合类型,但我不清楚如何根据传递给函数的字符串文字来缩小联合类型:
interface Response {
total: number
}
interface ApplesResponse extends Response {
apples: Array<object>
}
interface OrangesResponse extends Response {
oranges: Array<object>
}
type FruitResponse = ApplesResponse | OrangesResponse
const get = async (fruit: 'apples' | 'oranges') => {
const data: FruitResponse = await fetchFruit(`https://example.com/${fruit}`)
const count = data.total
const applesOrOranges = data[fruit].filter(Boolean)
}
解决方案
您可以使泛型 ( ) 的fruit
参数并解析依赖于的返回类型:get
K
K
type FruitResponse = ApplesResponse | OrangesResponse
type FruitResponseKeys = 'apples' | 'oranges' // or extract it from the response types
type FruitResponseByKey<K extends FruitResponseKeys> = Extract<FruitResponse,{ [P in K]: any }>
const get = async <K extends FruitResponseKeys>(fruit: K): Promise<FruitResponseByKey<K>> => {
// add validation logic for fetched data if you need that
// we cast it here as any for brevity
const data: FruitResponseByKey<K> = await fetch(`https://example.com/${fruit}`) as any
const applesOrOranges = data[fruit].filter(Boolean)
return { ...data, [fruit]: applesOrOranges }
}
const apples = get("apples") // Promise<ApplesResponse>
const oranges = get("oranges") // Promise<OrangesResponse>
FruitResponseByKey
基于. _ ApplesResponse
_ _ _ _OrangesResponse
FruitResponse
K
'apples' | 'oranges'
我认为,最有用的部分是,调用者根据fruit
键获得正确的水果数组。由于fetch
自然需要类型断言,我们只是any
为了简单起见在函数体中使用。此外,其中的逻辑get
没有任何复杂性,所以这应该很合适。
推荐阅读
- excel - 从 Workbook_Open() 运行时,Workbooks.Add 不会激活新工作簿
- python - 不确定的进度条不会在 python tkinter 中停止
- mysql - Mysql 拒绝完成某些命令,返回无穷无尽的 '<'
- php - Jquery 不发送 textarea name="post_description"
- java - 添加矩阵运算。矩形之间
- php - WordPress URL 重写新主机 URL
- string - 如何在 pandas df 中绘制与字符串数组关联的值?
- c# - 需要创建一个webservice来在同一个应用的两个版本之间发送消息
- python - OpenCV cv2.seamlessClone 中的边界错误
- python - 对象传递对象