我需要帮助将我在纸上写的一些具有挑战性的TS启发的伪代码转化为具体的TS。
type F<T, [x, ...r] extends ReadonlyArray<ReadonlyArray<keyof T>> =
Pick<T, ItemOf<X>> | F<T, R>;
// other approach explored
type F<T, U> =
U extends readonly [infer X, ...infer R] ?
X extends ReadonlyArray<keyof T> ?
Pick<T, ItemOf<X>> | F<T, R> : never : never;
为了完整起见,这里有一个 ItemOf
的定义,它实现了预期的目标,一个 "共产品类型 "的字面字符串("a" | "b" | ...
)的字面数组,准备提供给 Pick
:
type ItemOf<T> =
T extends ReadonlyArray<infer Item> ?
Item : never;
type Result = ItemOf<["a", "b"]> // successfully resolves to "a" | "b"
是否有可能像我想做的那样解包类型?我知道这可能会受到ML的启发,但我对它可能依赖的特性感兴趣,以便让这种类型漏斗定义在TS上工作 典型的用法将是。
type Struct = {x: string, y: string, z: string};
const Fields = [["x", "y"], ["z"]] as const;
type Result = F<Struct, typeof Fields> // should resolve to {x: string, y: string} | {z: string};
这对你有用吗?
type F<T, F extends readonly (readonly (keyof T)[])[]> =
{ [K in keyof F]: Pick<T, Extract<F[K], readonly (keyof T)[]>[number]> }[number]
type Result = F<Struct, typeof Fields>
// type Result = Pick<Struct, "x" | "y"> | Pick<Struct, "z">
我是把数组的键映射过来,然后对结果进行操作。 请注意,你可以获取数组中的元素。A
仰望 number
属性 (A[number]
). 如果这对你有用,我可能会展开答案来解释。 如果不行,请试着把你做的事情清楚地说出来(我很难跟上文字,对不起😳),也许可以用多个例子。
希望能帮到你,祝你好运!