「重学TS 2.0 」TS 练习题第二十题
Opened this issue · 16 comments
semlinker commented
实现一个 Curry
工具类型,用来实现函数类型的柯里化处理。具体的使用示例如下所示:
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = // 你的实现代码
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
请在下面评论你的答案。
sunboyZgz commented
//求指点感觉不是很对
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, ...infer B]
? B extends []
? (...args: [A]) => R
: (...args: [A]) => Curry<(...args: B) => R>
: () => R;
//
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
zhaoxiongfei commented
// 实现一个 Curry 工具类型,用来实现函数类型的柯里化处理。具体的使用示例如下所示:
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>,
> = P extends [infer A, ...infer B]
? B extends []
? (arg: A) => R
: (arg: A) => Curry<(...args: B) => R>
: R;
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
Honye commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, infer B, ...infer C]
? (arg: A) => Curry<(...args: [B, ...C]) => R>
: F;
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (a: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg: number) => (args_0: string) => Date
加强版本,保留原参数名
type FirstAsArray<T extends any[]> =
T extends [...infer A, infer B, infer C]
? A extends []
? T extends [...infer A, infer B] ? A : never
: T extends [...infer A, infer B] ? FirstAsArray<A> : never
: T;
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, infer B, ...infer C]
? P extends [infer A, ...infer B]
? Curry<F, FirstAsArray<P>, Curry<F, B, R>>
: never
: (...args: P) => R;
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (a: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (a: number) => (b: string) => Date
type F3 = Curry<(a: number, b: string, c: boolean) => Date> // (a: number) => (b: string) => (c: boolean) => Date
ln0y commented
保留参数名
type FirstAsArray<T extends any[]> = T extends [...infer A, infer B] ? A extends [] ? T : FirstAsArray<A> : []
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, ...infer B] ? B extends [] ? F : (...arg: FirstAsArray<P>) => Curry<(...arg: B) => R> : F
type LastAsArray<T extends any[]> = T extends [infer A, ...infer B] ? B extends [] ? T : LastAsArray<B> : []
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [...infer A, infer B] ? A extends [] ? F : Curry<(...args: A) => (...arg: LastAsArray<P>) => R> : F
type F0 = Curry<() => Date> // () => Date
type F1 = Curry<(a: number) => Date> // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date> // (arg_0: number) => (b: string) => Date
type F3 = Curry<(a: number, b: string, c: boolean) => Date> // (a: number) => (b: string) => (c: boolean) => Date
zhaoxiongfei commented
// 实现一个 Curry 工具类型,用来实现函数类型的柯里化处理。具体的使用示例如下所示:
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, ...infer B]
? B["length"] extends 0
? F
: (arg: A) => Curry<(...args: B) => R>
: F;
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
解题思路: 没啥特别要说的,依然是利用 extends 来探测参数的长度,利用递归逐渐减少参数个数。算法**是是减治。
Mrlgm commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer U, ...infer Arg] ? (arg: U) => Curry<F, Arg, R> : P extends [] ? () => R : never
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
safarishi commented
type Curry<F extends ((...args: any[]) => any)> = F extends ((arg_0: infer Arg, ...restArg: infer Rests) => any) ? (
Rests extends [] ? F : ((arg: Arg) => Curry<(...args: Rests) => ReturnType<F>>)
) : never
type F0 = Curry<() => Date> // () => Date
type F1 = Curry<(a: number) => Date> // (a: number) => Date
type F2 = Curry<(a: number, b: string) => Date> // (a: number) => (b: string) => Date
safarishi commented
//求指点感觉不是很对
type Curry< F extends (...args: any[]) => any, P extends any[] = Parameters<F>, R = ReturnType<F> > = P extends [infer A, ...infer B] ? B extends [] ? (...args: [A]) => R : (...args: [A]) => Curry<(...args: B) => R> : () => R; // type F0 = Curry<() => Date>; // () => Date type F1 = Curry<(a: number) => Date>; // (arg: number) => Date type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date
A 不需要用 [] 包起来
Flavour86 commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer F, ...infer Rest] ?
Rest extends [] ?
(arg:F) => R
: (arg:F) => Curry<(...args: Rest) => R>
: () => R
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg: number) => (arg: string) => Date
type F3 = Curry<(a: number, b: string, c: boolean) => Date>; // (arg: number) => (arg: string) => (arg: boolean) => Date
rookiecdn commented
柯里化 是啥意思
yang131323 commented
type Curry<F extends (...any: any[]) => any, A extends any[] = Parameters<F>> =
A extends [one: infer One, ...rest: infer Rest]
? A extends [one: any]
? F
: (a: One) => Curry<(...arg: Rest) => ReturnType<F>>
: F
SSSzhao commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer A, ...infer B]
? (arg: A) => B[number] extends never ? R : Curry<(arg: B[number]) => R>
: () => R
waleiwalei commented
保留参数名
type FirstAsArray<T extends any[]> = T extends [...infer A, infer B] ? A extends [] ? T : FirstAsArray<A> : [] type Curry< F extends (...args: any[]) => any, P extends any[] = Parameters<F>, R = ReturnType<F> > = P extends [infer A, ...infer B] ? B extends [] ? F : (...arg: FirstAsArray<P>) => Curry<(...arg: B) => R> : F type LastAsArray<T extends any[]> = T extends [infer A, ...infer B] ? B extends [] ? T : LastAsArray<B> : [] type Curry< F extends (...args: any[]) => any, P extends any[] = Parameters<F>, R = ReturnType<F> > = P extends [...infer A, infer B] ? A extends [] ? F : Curry<(...args: A) => (...arg: LastAsArray<P>) => R> : F type F0 = Curry<() => Date> // () => Date type F1 = Curry<(a: number) => Date> // (arg: number) => Date type F2 = Curry<(a: number, b: string) => Date> // (arg_0: number) => (b: string) => Date type F3 = Curry<(a: number, b: string, c: boolean) => Date> // (a: number) => (b: string) => (c: boolean) => Date
这个为什么可以保留参数名啊
LiuerQin commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters<F>,
R = ReturnType<F>
> = P extends [infer First, ...infer Rest] ?
Rest extends [] ?
F
:
(...args: [First]) => Curry<(...args: Rest) => R>
:F
dolphin0618 commented
柯里化 是啥意思
函数返函数
() => () => () => ''
dingzc2450 commented
type Curry<
F extends (...args: any[]) => any,
P extends any[] = Parameters,
R = ReturnType
> = P extends [infer P0, ...infer P1] ? (arg: P0) => P['length'] extends 1 ? R : Curry<((...args:P1)=>R)> : F;
type F0 = Curry<() => Date>; // () => Date
type F1 = Curry<(a: number) => Date>; // (arg: number) => Date
type F2 = Curry<(a: number, b: string) => Date>; // (arg_0: number) => (b: string) => Date