现在已经 4 年了,但我设法得到了一个没有重载的类型化版本:
需要做一些讨厌的事情:
我们需要数字列表有两个原因:
- 给定一个特定的索引,我们需要能够检索以前的索引
- 我们需要能够将字符串元组索引转换为数字索引
type SNumbers = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31",
"32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47",
"48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63"];
type Numbers = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63];
// Util to prepend a value to a Tuple from: https://stackoverflow.com/a/54607819/5308589
type PrependTuple<A, T extends Array<any>> =
(((a: A, ...b: T) => void) extends (...a: infer I) => void ? I : [])
// Get the previous number (for indexing) (2=>1, 1=>0, 0=>never)
type PrevN<T extends number> = PrependTuple<never, Numbers>[T];
// Convert a string index to a number
type S_N<S extends SNumbers[number]> = {
[K in SNumbers[number]]: Numbers[K]
}[S]
几个帮手:
Pipe/Compose 作用于一元函数
// Only unary functions wanted
type Unary = (i: any) => any;
// Get the (single) argument of a given unary function
type ParameterUnary<F extends Unary> = Parameters<F>["0"]
// ReturnType is a builtin
主要类型:
UnariesToPiped/UnariesToComposed 采用一元函数元组并尝试将其映射到包含正确函数类型的元组
然后 Pipe/Compose 只需将映射的元组作为参数,并拉取第一个参数类型和最后一个返回类型。
type UnariesToPiped<F extends Unary[]> = {
[K in keyof F]:
K extends SNumbers[number]
? K extends "0"
? F[K]
: (i: ReturnType<F[PrevN<S_N<K>>]>) => ReturnType<F[S_N<K>]>
: F[K]
}
type Pipe = <F extends Unary[]>(...funcs: UnariesToPiped<F>) => (i: ParameterUnary<F[0]>) => ReturnType<F[PrevN<F["length"]>]>
type UnariesToComposed<F extends Unary[]> = {
[K in keyof F]:
K extends SNumbers[number]
? K extends "0"
? F[K]
: (i: ParameterUnary<F[S_N<K>]>) => ParameterUnary<F[PrevN<S_N<K>>]>
: F[K]
}
type Compose = <F extends Unary[]>(...funcs: UnariesToComposed<F>) => (i: ParameterUnary<F[PrevN<F["length"]>]>) => ReturnType<F[0]>
有关使用示例,我已将其发布到 Github 和 NPM