我有时会遇到这种问题,但我不确切地知道为什么推理不起作用.
在这种情况下,zip
在直接应用时返回正确的类型,但在通过pipe
应用时不返回正确的类型,我不知道为什么.
declare const zip: {
<A, B>(input: readonly [readonly A[], readonly B[]]): [A, B][],
<A, B, C>(input: readonly [readonly A[], readonly B[], readonly C[]]): [A, B, C][],
<A, B, C, D>(input: readonly [readonly A[], readonly B[], readonly C[], readonly D[]]): [A, B, C, D][],
<A extends readonly any[]>(input: readonly A[]): A[0][][],
};
declare const pipe: <A, B>(a: A, f: (a: A) => B) => B;
declare const x: [number[], string[], boolean[]];
const foo = pipe(x, zip);
// ^? foo: any[][]
const bar = pipe(x, x => zip(x))
// ^? bar: [number, string, boolean][]
playground个 这不是什么大事,但它真的让我感到困惑,因为它可能会浪费时间来理解为什么有些东西不能编译,或者浪费了试图键入一些东西以使其最终不像预期的行为的努力.
顺便说一句,这个pipe
函数是以下内容的摘录,它在大多数情况下都有效(显然不是这个),但看起来有点难
const pipe: {
<A>(
a: A
): A
<A, B>(
a: A,
f: (a: A) => B
): B
<A, B, C>(
a: A,
f: (a: A) => B,
g: (b: B) => C
): C
<A, B, C, D>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D
): D
<A, B, C, D, E>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E
): E
<A, B, C, D, E, F>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E,
j: (e: E) => F
): F
<A, B, C, D, E, F, G>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E,
j: (e: E) => F,
k: (f: F) => G
): G
<A, B, C, D, E, F, G, H>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E,
j: (e: E) => F,
k: (f: F) => G,
l: (g: G) => H
): H
<A, B, C, D, E, F, G, H, I>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E,
j: (e: E) => F,
k: (f: F) => G,
l: (g: G) => H,
m: (h: H) => I
): I
<A, B, C, D, E, F, G, H, I, J>(
a: A,
f: (a: A) => B,
g: (b: B) => C,
h: (c: C) => D,
i: (d: D) => E,
j: (e: E) => F,
k: (f: F) => G,
l: (g: G) => H,
m: (h: H) => I,
n: (i: I) => J
): J
}
您可能会认为,嘿,使用映射类型,您可以得出如下内容(不要注意细节)
import { Lift, free, Init, Tail } from 'free-types';
declare const pipe: {
<A,B>(a: A, ...fns: Fns<[A, B]>): B
<A,B, C>(a: A, ...fns: Fns<[A, B, C]>): C
<A,B, C, D>(a: A, ...fns: Fns<[A, B, C, D]>): D
<A,B, C, D, E>(a: A, ...fns: Fns<[A, B, C, D, E]>): E
<A,B, C, D, E, F>(a: A, ...fns: Fns<[A, B, C, D, E, F]>): F
<A,B, C, D, E, F, G>(a: A, ...fns: Fns<[A, B, C, D, E, F, G]>): G
<A,B, C, D, E, F, G, H>(a: A, ...fns: Fns<[A, B, C, D, E, F, G, H]>): H
<A,B, C, D, E, F, G, H, I>(a: A, ...fns: Fns<[A, B, C, D, E, F, G, H, I]>): I
<A,B, C, D, E, F, G, H, I, J>(a: A, ...fns: Fns<[A, B, C, D, E, F, G, H, I, J]>): J
};
type Fns<Fs extends [unknown, ...unknown[]]> = Lift<free.UnaryFunction, [Init<Fs>, Tail<Fs>]>
但由于某些原因,它只适用于单态函数.我try 了更简单的设计,但基本上在某一点上会有一种间接的方式会使编译器松动,我真的无法预测它.更长/更简单的pipe
版本是您在大多数FP库中找到的版本,这显然是有充分理由的.
你能解释一下zip
的情况吗?如果你对更复杂的pipe
版本有什么 idea ,请随时与我们分享.