如何根据键值推断类型?

问题描述 投票:0回答:1

我正在尝试推断

getAllRaces()
的类型是
() => Race[]
.

到目前为止我试过:

type CollectionMap = {
    races: Race[]
    horses: Horse[]
}

type Race = {
    date: Date
}

type Horse = {
    name: string
}

type UnionizeKeys<T> = {
    [k in keyof T]: k
}[keyof T]

type CollectionName = UnionizeKeys<CollectionMap> // "races" | "horses"

// Failed attempts

const getAll1 = (name: CollectionName) =>  [] as CollectionMap[name];
// 💥 Type 'name' cannot be used as an index type.(2538)

const getAll2 = (name: CollectionName) =>  [] as CollectionMap[typeof name as const];
// 💥 A 'const' assertions can only be applied to references to enum members,
//    or string, number, boolean, array, or object literals.(1355)

const getAll = (name: CollectionName) =>  [] as CollectionMap[typeof name];

const getAllRaces = () => getAll('races')
// ❌ const getAllRaces: () => Race[] | Horse[]
// ✅ const getAllRaces: () => Race[]

TypeScript 游乐场

非常感谢您的帮助

typescript
1个回答
1
投票

如果你想让

getAll()
的返回类型依赖于
name
输入,你可以在K中让它成为
generic
name
输入的类型,其中
K
constrained
keyof CollectionMap
(和你的
CollectionName
类型一样,写得比回旋处更直接
UnionizeKeys
):

const getAll = <K extends keyof CollectionMap>(
    name: K
): CollectionMap[K] => [];

返回类型只是 索引访问类型

CollectionMap[K]
CollectionMap
的属性类型,键类型为
K
.

让我们测试一下:

const getAllRaces = () => getAll('races')
// const getAllRaces: () => Race[]
const getAllHorses = () => getAll('horses');
// const getAllHorses: () => Horse[]

看起来不错。

游乐场代码链接

© www.soinside.com 2019 - 2024. All rights reserved.