我有一个定义如下的缓存(片段):
interface Cache {
chapterDates: { [workId: string]: string[] };
kudosChecked: number[];
}
export const DEFAULT_CACHE: Cache = {
chapterDates: {},
kudosChecked: [],
};
我希望能够定义一个函数,当给它一个诸如“ chapterDates”或“ kudosChecked”之类的缓存键作为字符串时,它将以适当的属性类型返回缓存的值。
到目前为止,我已经尝试使用条件类型进行以下操作:
type Test<T> = T extends 'chapterDates'
? { [workId: string]: string[] }
: T extends 'kudosChecked'
? number[]
: never;
export async function getCache<T extends keyof Cache, R extends Test<T>>(
id: T
): Promise<R> {
[...]
}
我也尝试过:
export async function getCache<
T extends keyof Cache,
R extends Cache[T]
>(id: T): Promise<R> {
[...]
}
解决方案似乎都无法使打字稿理解例如返回类型为getCache('kudosChecked')
应该是number[]
。目前似乎认为它是number[] | { [workId: string]: string[] }
。
我要完全解决这个问题吗?我对打字稿很陌生吗?
答案 0 :(得分:0)
好的,所以我终于解决了许多打字稿问题,终于找到了解决方法。帮助的问题是microsoft/Typescript#39305。它建议ValueOf
为
type KeyOf<
U,
C = unknown,
K extends U extends unknown ? keyof U : never = U extends unknown
? keyof U
: never
> = C extends unknown
? U extends unknown
? K extends unknown
? U[K] extends C
? K
: never
: never
: never
: never;
type ValueOf<U, K extends KeyOf<U> = KeyOf<U>> = U extends unknown
? K extends keyof U
? U[K]
: never
: never;
使用这种新类型,我们可以这样定义getCache
:
export async function getCache<K extends CacheId, R = ValueOf<Cache, K>>(
id: K
): Promise<R> {
[...]
}