【发布时间】:2018-02-07 08:33:41
【问题描述】:
我目前正在使用typescript@next,它现在已经合并了Conditional Types PR。
我正在尝试创建一个方法,该方法为数据模型类型获取深度记录,并根据记录中的字段返回一种深度选择。例如,我希望能够做到以下几点:
loadUser({
id: true,
name: {
first: true
}
});
User 类型的样子
type User = {
name: {
first: string;
last: string;
};
id: string;
}
在这种情况下loadUser 的返回值将匹配
{
id: string;
name: {
first: string;
}
}
到目前为止,我所做的如下:
type DeepSelect<T> = {[K in keyof T]?: T[K] extends string ? boolean : DeepSelect<T[K]>};
type DeepPick<T, S extends DeepSelect<T>> = {[K in keyof S]: S[K] extends DeepSelect<infer U> ? DeepPick<T[K], U> : T[K]}
function loadUser<S extends DeepSelect<User>>(select: S): DeepPick<User, S> {
...
}
问题有两个方面:
- 在
DeepPick定义中使用T[K]时出现type K cannot be used to index type T错误。
我觉得考虑到DeepSelect 的定义,其中所有键都来自通用T 中的键,T[K] 在这里完全有效,因为S 中的任何键也将是@987654337 中的键@。
2。在DeepPick 定义中最后一次使用S[K] 错误说type boolean | DeepSelect<T[K]> is not assignable to type DeepSelect<T[K]>
在这里,我觉得因为这部分类型条件只有在S[K]没有扩展布尔值时才会被命中,那么它应该能够推断出S[K]不是boolean | DeepSelect<T[K]>而是只是@ 987654344@
我意识到,由于这个 PR 是昨天才合并的,所以没有多少人会对这些问题有深入的了解,但如果有人能帮助我了解如何正确构建这些类型,我将非常感激。
更新 1
好的,我想我已经使用同样新的 Type Inference 解决了问题 #2。我已将 DeepPick 类型的定义从:
type DeepPick<T, S extends DeepSelect<T>> = {[K in keyof S]: S[K] extends boolean ? T[K] : DeepPick<T[K], S[K]>}
到:
type DeepPick<T, S extends DeepSelect<T>> = {[K in keyof S]: S[K] extends DeepSelect<infer U> ? DeepPick<T[K], U> : T[K]}
【问题讨论】:
标签: typescript typescript-typings