-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Description
Suggestion
π Search Terms
implicit function types
β Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
β Suggestion
function literals should implicitly have a type - the same way class literals do.
π Motivating Example
Currently, to use dependency injection with functions, I have to explicitly add types for function literals, like so:
function sayHello(user: string) {
window.alert(`Hello, ${user}!`);
}
type sayHello = typeof sayHello; // π this
function start(sayHello: sayHello) {
// ...
}Intuitively, before you try that, you're going to try something this:
function sayHello(user: string) {
window.alert(`Hello, ${user}!`);
}
function start(sayHello: typeof sayHello) {
// ...
}That doesn't work.
Contrast function declarations with class declarations, which "just works":
class HelloSayer {
// ...
}
function start(sayHello: HelloSayer) {
// ...
}Why do class declarations get a type, and function declarations don't?
It's also not unconventional in JS to write "constructor" functions like this:
function HelloSayer(user: string) {
return {
sayHello() {
window.alert(`Hello, ${user}!`);
}
}
}
function start(sayHello: HelloSayer) {
// ...
}There's even been popular talk of "new keyword considered harmful" over the years.
In JavaScript, the result of a class declaration isn't very different from the result of a function declaration - both result in a function type value in the same scope. Both are declarations parsed during the first pass, meaning you can reference them recursively.
And functions do have a type in TypeScript: you can extract it with typeof, and you can import it from another module with import type, so why is this type "hidden" or inaccessible from type-hints? Why do classes have this special status?
I think this could be "fixed" retroactively without any breaking changes, if declaration merging could be applied, allowing existing code to explicitly declare an identical function-type with e.g. type HelloSayer = typeof HelloSayer, since these would almost definitely have identical types. (Or, at least, this would be a very minor breaking change, only affecting codebases where some types are currently inconsistent with the types of function literals with the same name.)
π» Use Cases
Dependency injection.