类型仿函数和文字数组拆包

Type functor and literal array unpacking

我需要帮助将我在纸上写的一些具有挑战性的 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 定义,它执行预期的操作,来自文字数组的 "coproduct type" 文字字符串 ("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">

我正在映射键数组并处理结果。请注意,您可以通过查找 number 属性 (A[number]) 来获取数组 A 的元素。如果这对您有用,我可以扩展答案进行解释。如果不是,请尝试清楚地说明您在做什么(对不起,我无法理解文本),并且可能有多个示例。

希望对您有所帮助;祝你好运!

Playground link to code