我正在尝试推断
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[]
非常感谢您的帮助
如果你想让
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[]
看起来不错。