4 ms·
There is complexity in the type system with signatures like ``` function partialCall<T extends Arr, U extends Arr, R>(f: (...args: [...T, ...U]) => R, ...headA
by zaphirplane 6y ago
There is complexity in the type system with signatures like
```
function partialCall<T extends Arr, U extends Arr, R>(f: (...args: [...T, ...U]) => R, ...headArgs: T) {
`
- kelnos 6y agoIt's funny that you consider that complex; I consider that a pretty normal, expressive type signature that gives the compiler critical information about how I expect to use that function, which in turn allows it to completely squash several classes of bugs I might write. But I love strong type systems; people who prefer weak type systems would likely consider things like this to get in their way.
- melq 6y agoCould you elaborate on this point for someone who isn't familiar with typescript (or javascript, for that matter). I'm no stranger to strongly typed languages but that function signature seems pretty complex to me. By elaborate I mean explain what's going on in that signature, and what the critical information it supplies is?
- flatline 6y agoI would say, there is some complexity in reading (and writing) the thing. But there is probably not as much complexity in using it. And you are explicitly codifying the complexity in one place, that would presumably still exist in a dynamically typed language, just implicitly, and likely spread out across the code. This looks pretty nice to me at a glance, just like anything once you write a few of them and come across a few in the wild and take the time to pick them apart they no longer seem so scary.
- jcheng 6y agoIt's from the TypeScript 4.0 beta blog post[0], which describes it as: > partialCall takes a function along with the initial few arguments that that function expects. It then returns a new function that takes any other arguments the function needs, and calls them together. The type signature looks like: type Arr = readonly unknown[]; function partialCall<T extends Arr, U extends Arr, R>(f: (...args: [...T, ...U]) => R, ...headArgs: T) { First of all, know that in TypeScript, colon separates a variable or parameter name from its type. So in C or Java you'd say "Date lastModified", in TypeScript it's "lastModified: Date". Now, looking at it piece by piece: function partialCall declares a function named partialCall. <T extends Arr, U extends Arr, R> says that this is a generic function with type parameters T, U, and R (the first two of which must extend Arr, that is, a readonly array of objects whose types are unknown). This function's first parameter is: f: (...args: [...T, ...U]) => R The name of the parameter is `f`, and the type of this parameter is `(...args: [...T, ...U]) => R`. This means that `f` must be a function whose return type is R, and its parameters must match `...args: [...T, ...U]`. The `...` in `...args` makes it a rest parameter[1] (variadic parameter in other languages). The type of `...args` is `[...T, ...U]`, which you can think of as the concatenation of the T and U arrays. (It's a bit strange to see `...` in a type specifier, I can't recall having needed this before.) ...headArgs: T says that the `partialCall` function itself is also variadic, and its arguments are gathered up into headArgs. The type of headArgs is T. I don't know if I'd call this normal or clear compared to the signatures I encounter daily, but it's pretty elegant for a higher-order function that takes a function with any signature, and some arguments that match the given function's parameters, and returns a function with the matched parameters removed. And the implementation of partialCall is just this one line! return (...b: U) => f(...headArgs, ...b) [0]: https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/ https://devblogs.microsoft.com/typescript/announcing-typescr... [1]: https://www.typescriptlang.org/docs/handbook/functions.html#rest-parameters https://www.typescriptlang.org/docs/handbook/functions.html#...
- melq 6y agoThank you for taking the time to explain that, it is much appreciated.
- deleted 6y ago[deleted]
- no_wizard 6y agoAt least I can pick it apart and deduce it. I can even use the compiler to give me information about it via editor integration (all same editors have it now). So I’ve I’m unsure it might take a few minutes of investigation to completely understand the signature. I’ve seen some JavaScript written so tersely it was nearly impossible to figure out without spending Possibly hours on unwrapping the code. That’s the value provided here.
- IggleSniggle 6y agoWhen it comes to spending hours unwrapping code, gotta love js that has undocumented heavy use of string based property access for things like imports. Like the worst of both functional and OOP combined, and generally no IDE support to be had. Implementation approximate, but otherwise true story, both LHS and RHS: `let { statefulMutatingAccessor } = require(obj["prop."+tree+".subtree"])`