Skip to content

Instantly share code, notes, and snippets.

@lierdakil
Last active July 26, 2019 10:29
Show Gist options
  • Save lierdakil/92256af3fae9fea9cf43688d0b98edcb to your computer and use it in GitHub Desktop.
Save lierdakil/92256af3fae9fea9cf43688d0b98edcb to your computer and use it in GitHub Desktop.
Proper, if limited, type for Function.bind
#!/bin/bash
max=10
end=""
t=" "
echo "interface Bind {"
echo "${t}<T extends (...args: any[]) => any>(this: T, thisArg: any): T$end"
for i in `seq 1 $max`; do
echo -n "${t}<T extends ("
for j in `seq 1 $i`; do
echo -n "x$j: U$j, "
done
echo -n "...args: any[]) => any, "
for j in `seq 1 $i`; do
echo -n "U$j, "
done
echo -n ">(this: T, thisArg: any, "
for j in `seq 1 $i`; do
echo -n "x$j: U$j, "
done
echo ")"
for j in `seq 1 $max`; do
echo -n "${t}${t}: T extends ("
m=$([ $i -ge $j ] && echo $j || echo $i)
for k in `seq 1 $m`; do
echo -n "x$k: U$k, "
done
for k in `seq $(($m+1)) $j`; do
echo -n "x$k: infer U$k, "
done
echo -n ") => any ? ("
for k in `seq $(($i+1)) $j`; do
echo -n "x$k: U$k, "
done
echo ") => ReturnType<T>"
done
echo "${t}${t}: (...args: any[]) => ReturnType<T>$end"
done
i=$(($max+1))
echo -n "${t}<T extends ("
for j in `seq 1 $i`; do
echo -n "x$j: U$j, "
done
echo -n "...args: any[]) => any, "
for j in `seq 1 $i`; do
echo -n "U$j, "
done
echo -n ">(this: T, thisArg: any, "
for j in `seq 1 $i`; do
echo -n "x$j: U$j, "
done
echo "...argArray: any[])"
echo "${t}${t}: (...args: any[]) => ReturnType<T>$end"
echo "}"
cat <<EOF
interface Function {
${t}bind: Bind$end
}
EOF
interface Bind {
<T extends (...args: any[]) => any>(this: T, thisArg: any): T
<T extends (x1: U1, ...args: any[]) => any, U1, >(this: T, thisArg: any, x1: U1, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: infer U2, ) => any ? (x2: U2, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, ) => any ? (x2: U2, x3: U3, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, ) => any ? (x2: U2, x3: U3, x4: U4, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: infer U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, ...args: any[]) => any, U1, U2, >(this: T, thisArg: any, x1: U1, x2: U2, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, ) => any ? (x3: U3, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, ) => any ? (x3: U3, x4: U4, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, ) => any ? (x3: U3, x4: U4, x5: U5, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, ) => any ? (x3: U3, x4: U4, x5: U5, x6: U6, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, ) => any ? (x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, ) => any ? (x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: infer U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, ...args: any[]) => any, U1, U2, U3, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, ) => any ? (x4: U4, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, ) => any ? (x4: U4, x5: U5, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, x6: infer U6, ) => any ? (x4: U4, x5: U5, x6: U6, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, ) => any ? (x4: U4, x5: U5, x6: U6, x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, ) => any ? (x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: infer U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, ...args: any[]) => any, U1, U2, U3, U4, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, ) => any ? (x5: U5, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, x6: infer U6, ) => any ? (x5: U5, x6: U6, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, x6: infer U6, x7: infer U7, ) => any ? (x5: U5, x6: U6, x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, ) => any ? (x5: U5, x6: U6, x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: infer U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ...args: any[]) => any, U1, U2, U3, U4, U5, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: infer U6, ) => any ? (x6: U6, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: infer U6, x7: infer U7, ) => any ? (x6: U6, x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: infer U6, x7: infer U7, x8: infer U8, ) => any ? (x6: U6, x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x6: U6, x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: infer U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: infer U7, ) => any ? (x7: U7, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: infer U7, x8: infer U8, ) => any ? (x7: U7, x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: infer U7, x8: infer U8, x9: infer U9, ) => any ? (x7: U7, x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: infer U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x7: U7, x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, U7, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: infer U8, ) => any ? (x8: U8, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: infer U8, x9: infer U9, ) => any ? (x8: U8, x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: infer U8, x9: infer U9, x10: infer U10, ) => any ? (x8: U8, x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, U7, U8, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: infer U9, ) => any ? (x9: U9, ) => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: infer U9, x10: infer U10, ) => any ? (x9: U9, x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, U7, U8, U9, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: infer U10, ) => any ? (x10: U10, ) => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, )
: T extends (x1: U1, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, ) => any ? () => ReturnType<T>
: T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, ) => any ? () => ReturnType<T>
: (...args: any[]) => ReturnType<T>
<T extends (x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, x11: U11, ...args: any[]) => any, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, >(this: T, thisArg: any, x1: U1, x2: U2, x3: U3, x4: U4, x5: U5, x6: U6, x7: U7, x8: U8, x9: U9, x10: U10, x11: U11, ...argArray: any[])
: (...args: any[]) => ReturnType<T>
}
interface Function {
bind: Bind
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment