Abir Sheikh
Abir Sheikh

Reputation: 543

Function call signature gives error if the function was declared without `const` keyword

I'm new to TypeScript and while learning Call Signatures, I keep getting error if I store the function with let or const keyword. Like So:

Call signature

type Foo = {
    desc: string,
    (arg: string): void
}

If I create a function and store it using let or var keyword,

let bar: Foo = function(arg: string): void{
    console.log(arg);
}
bar.desc = 'baz';

I get following error:

 error TS2741: Property 'desc' is missing in type '(arg: string) => void' but required in type 'Foo'.

However, if I store the function in a constant variable, it works as expected

type Foo = {
    desc: string,
    (arg: string): void
}

const bar: Foo = function(arg: string): void{
    console.log(arg);
}
bar.desc = 'baz';

Are there any specific reason behind it? Am I missing something?

Upvotes: 3

Views: 100

Answers (1)

jcalz
jcalz

Reputation: 328548

Support for adding properties to functions was introduced in TypeScript 3.1 as implemented in microsoft/TypeScript#26368. The feature is documented specifically as:

Allow JS-container (expando) property assignments in Typescript, but only for function declarations and function/arrow expressions used as initialisers of const variables.

So this is working as intended; const variables initialized with functions can have properties added to them, but there is no support for let or var.


Curiously I don't see any authoritative source for exactly why let and var are not supported. Instead, all I can offer is an educated guess: it is because control flow analysis on function statements and const variables is much easier than it is for var or let variables. A function statement and a const variable cannot be reassigned, so once you know that there is an extra property on the function, that property will continue to exist unless someone modifies the property directly. On the other hand, a var or let could be reassigned, meaning that the compiler would need to check to see that this did not happen between the adding of the property and its attempted use, which could be quite complicated depending on scopes.

So, my expectation is that the feature was added to support the simple cases, and that the more complicated cases are not yet supported because there hasn't been much demand for them, if any. If you have some important use case for it (some reason why const is insufficient), you might want to file a feature request.

Upvotes: 5

Related Questions