4 ms·
Am I the only one that thinks "function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); }" looks horrible?
by mcraiha 8y ago
Am I the only one that thinks
"function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R {
return fn(...args);
}"
looks horrible?
- vbezhenar 8y agoVery clear for me. What's horrible about it?
- baq 8y agoAny notation you're not familiar with looks horrible.
- brainzap 8y agoyes it seems a bit much at first glance, I hope the learning curve for beginners is not too steep.
- tomjen3 8y agoIt should be formatted better, but other than that, I don't see the problem; yes it is hard to parse, but that is because a lot is going on.
- dested 8y agoI imagine most code bases will contain a very small number (probably zero) type definitions with a spread tuple type. There are only so many ways to solve being type safe in a language that is so permissive, and sometimes it causes the result to look ugly. Ideally 95% of end users will never need to type this, only rely on it.
- brlewis 8y ago"For this function named `call`, the first argument must be a function `fn`, and subsequent arguments must be the type of arguments that `fn` expects. The return value of `call` is the same type as the return value of `fn`." How would you recommend communicating all that in an extended version of ECMAscript?
- frankpf 8y agoI like TypeScript's syntax, but I think the way function types are declared is ugly. If you have a function from A to B, you have to declare its type as type MyFunction = (arg1: A) => B instead of type MyFunction = A => B Here's that syntax applied to the example from GP: function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); } vs. function call<TS extends any[], R>(fn: ...TS => R, ...args: TS): R { return fn(...args); }
- eppsilon 8y agoThe syntax is probably meant to differentiate between a function expression and a function type declaration.
- wvenable 8y agoIt's a rather complex construct: A function that takes a function and a list of arguments that calls that function with those arguments. This construct would actually be more complex if the parameter list types were actually specified instead of being any[].
- mixedCase 8y agoYes, it is aesthetically ugly. But as someone who has used TypeScript for a handful of months, it's very easy to read.
- w0rd-driven 8y agoIt's hard to gauge its looks as unfamiliar with TS as I am but would the equivalent without the spread operator look any better? I call code like this 'clever' as it uses the language constructs to get usually a very optimal end result at the behest of being harder for n00bs like myself to parse. I do wonder what a prettier version of this would look like. It certainly wouldn't be this concise but would it be better or harder to follow? I'm okay with something like this if it solves a very specific problem I hardly see. If my entire code base is littered with this? No thanks. Yea eventually it'd be second nature but I'd rather it be more verbose and slightly easier to unpack than this tightly packed.
- deleted 8y ago[deleted]
- Too 8y agoFirst of all: That is both the function definition and implementation on the same row! Make line breaks around the curly braces. Secondly, the (...args: TS) => R can be extracted into another type/interface, this way you would just get "function call<TS extends any[], R>(fn: Callable<TS, R>, ...args: TS): R"