ramda 为 占位符 添加类型

原创
10/02 15:43
阅读数 26

https://medium.com/free-code-camp/typescript-curry-ramda-types-f747e99744ab

 

 拿到占位符类型, 然后获取参数长度已经对参数长度做加减

type __ = typeof R.__;
type Pos<I extends any[]> = Length<I>;
type Next<I extends any[]> = Prepend<any, I>;
type Prev<I extends any[]> = Tail<I>;
type a07 = [any, any];
type t30 = Pos<a07>;
// type t30 = 2

type t31 = Pos<Next<a07>>;
// type t31 = 3

type t32 = Pos<Prev<a07>>;
// type t32 = 1

 

构造元组


type Iterator<
  Index extends number = 0,
  From extends any[] = [],
  I extends any[] = []
> = {
  0: Iterator<Index, Next<From>, Next<I>>;
  1: From;
}[Pos<I> extends Index ? 1 : 0];

type t33 = Iterator<2>;
// type t33 = [head: any, head: any]

type t34 = Iterator<3, t33>;
// type t34 = [head: any, head: any, head: any, head: any, head: any]

type t35 = Pos<t33>;
// type t35 = 2

type t36 = Pos<t34>;
// type t36 = 5

 

 

反转

type Reverse<T extends any[], R extends any[] = [], I extends any[] = []> = {
  0: Reverse<T, Prepend<T[Pos<I>], R>, Next<I>>;
  1: R;
}[Pos<I> extends Length<T> ? 1 : 0];

type t37 = Reverse<[1, 2, 3]>;
// type t37 = [head: 3, head: 2, head: 1]

type t38 = Reverse<t37>;
// type t38 = [head: 1, head: 2, head: 3]

type t39 = Reverse<[3, 2, 1], [6, 4, 5]>;
// type t39 = [1, 2, 3, 6, 4, 5]

type t40 = Reverse<t39>;
// type t40 = [head: 5, head: 4, head: 6, head: 3, head: 2, head: 1]

 

链接和头部添加


type Concat<T1 extends any[], T2 extends any[]> = Reverse<
  Cast<Reverse<T1>, any[]>,
  T2
>;

type t41 = Concat<[1, 2], [5, 6]>;
// type t41 = [1, 2, 5, 6]

type Append<E, T extends any[]> = Concat<T, [E]>;

type t42 = Append<3, [1, 2]>;
// type t42 = [1, 2, 3]

 

取指定位置占位符所对应的类型


type GapOf<
  T1 extends any[],
  T2 extends any[],
  TN extends any[],
  I extends any[]
> = T1[Pos<I>] extends __ ? Append<T2[Pos<I>], TN> : TN;

type t43 = GapOf<[__, __], [number, string, boolean], [], Iterator<0>>;
// type t43 = [number]

type t44 = GapOf<[__, __], [number, string, boolean], [], Iterator<1>>;
// type t44 = [string]

type t45 = GapOf<[__, __], [number, string, boolean], [], Iterator<2>>;
// type t45 = [boolean]

 

 

取所有占位符对应的类型


type GapsOf<
  T1 extends any[],
  T2 extends any[],
  TN extends any[] = [],
  I extends any[] = []
> = {
  0: GapsOf<T1, T2, Cast<GapOf<T1, T2, TN, I>, any[]>, Next<I>>;
  1: Concat<TN, Cast<Drop<Pos<I>, T2>, any[]>>;
}[Pos<I> extends Length<T1> ? 1 : 0];

type t46 = GapsOf<[__, any, __], [number, string, object, string[]]>;
// type t46 = [number, object, string[]]

type t47 = GapsOf<[__, any, __], [number, string, object, string[]]>;
// type t47 = [number, object, string[]]

type t48 = GapsOf<[__, __, __], [number, string, object, string[]]>;
// type t48 = [number, string, object, string[]]

// 这个测试有问题, 会有undefined混入了, 同时应该报错
type t49 = GapsOf<[__, __, __], [object, string[]]>;
// type t49 = [head: object, head: string[], head: undefined]

 

清空undefined


type PartialGaps<T extends any[]> = {
  [K in keyof T]?: T[K] | __;
};

type t50 = PartialGaps<[number, string]>;
// type t50 = [(number | R.Placeholder)?, (string | R.Placeholder)?]

type CleanedGaps<T extends any[]> = {
  [K in keyof T]: NonNullable<T[K]>;
};

type t51 = CleanedGaps<PartialGaps<[number, string]>>;
// type t51 = [(number | R.Placeholder)?, (string | R.Placeholder)?]

type Gaps<T extends any[]> = CleanedGaps<PartialGaps<T>>;

type t52 = Gaps<[number, string]>;
// type t52 = [(number | R.Placeholder)?, (string | R.Placeholder)?]

 

最终版, 有了参数类型和函数类型的提示


type CurryV6<P extends any[], R> = <T extends any[]>(
  ...args: Cast<T, Gaps<P>>
) => GapsOf<T, P> extends [any, ...any[]]
  ? CurryV6<Cast<GapsOf<T, P>, any[]>, R>
  : R;

declare function CurryV6<P extends any[], R>(
  f: (...args: P) => R
): CurryV6<P, R>;

const f6 = (name: string, age: number, single: boolean) => true;
const curry6 = CurryV6(f1);
const r6 = curry6("", 1, true);
// const r6: boolean

const r7 = curry6("", 1);
// const r7: CurryV6<[single: boolean], boolean>

// 支持了占位符
const r8 = curry6("", R.__)("")(true);
// Argument of type 'string' is not assignable to parameter of type 'number | Placeholder'.ts(2345)

// 支持参数提示
const r9 = curry6("")();

type CurryV7<F extends (...args: any[]) => any> = <T extends any[]>(
  ...args: Cast<Cast<T, Gaps<Parameters<F>>>, any[]>
) => GapsOf<T, Parameters<F>> extends [any, ...any[]]
  ? CurryV7<(...args: Cast<GapsOf<T, Parameters<F>>, any[]>) => ReturnType<F>>
  : ReturnType<F>;

declare function CurryV7<F extends (...args: any[]) => any>(f: F): CurryV7<F>;

const f7 = (name: string, age: number, single: boolean) => true;
const curry7 = CurryV7(f7);
const r10 = curry7("", 1, true);
const r11 = curry7("", 1);

// 支持了占位符
const r12 = curry7("", R.__)("")(true);
const r13 = curry7("")();

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部