type-challenges / type-challenges

Collection of TypeScript type challenges with online judge
https://tsch.js.org/
MIT License
42.98k stars 4.67k forks source link

462 - Currying 2 - with explainations #18047

Open Mantou1233 opened 1 year ago

Mantou1233 commented 1 year ago
declare function DynamicParamsCurrying<T extends any[], R>(fn: (...args: T) => R):  
  T extends [] ? R : // returns R if no params is needed
    <P extends any[]>(...args: P) => 
      T extends [...P, ...infer K3] ? // check does P & K3 extends T, basically checking is P fully T
        ReturnType<typeof DynamicParamsCurrying<K3, R>> : // Pass in K3 and T to check is K3 = T
      R;
Mantou1233 commented 1 year ago

this isnt a hard one but really requires thinking

Alexsey commented 1 year ago

The solution is really nice, but it is not strict enough: it allows things like

curried1('123')(123)('anything')
kstratis commented 1 year ago

@Mantou1233 ~Can you please explain how your solution works? I'm really baffled here...~ Never mind. Eventually figure out. Problem with this solution though is that it doesn't enforce types on each function call. For example:

const curried1 = DynamicParamsCurrying(
  (a: string, b: number, c: boolean) => true
);

const test = curried1(true, true, true)  // <-- This looks valid! No squiggly lines here!

The example above ☝️ shouldn't be the case. @Alexsey was right all along.