Reputation: 632
The typescript documentation talks about function call signatures
and construct signatures
and describes how you can declare the type and use it. https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures
call signatures (with no implemetation of a function with type DescribableFunction
)
type DescribableFunction = {
description: string;
(someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6));
}
construct signatures(with no implementation of a function with type SomeConstructor
)
type SomeConstructor = {
new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
return new ctor("hello");
}
But it never shows how to define the actual implementation of such functions. And I searched a lot for days, but can't seem to find anything on it. A simple example of each with how to use it and when you would use it would be very helpful in understanding these concepts.
I tried to do it like this of call signatures
but obviously its throwing error
type DescribableFunction = {
description: string;
(str: string): string;
}
const df: DescribableFunction = {
description: 'df function description',
(str: string): {
return str;
}
}
console.log(df.description, df('hello world'));
Upvotes: 2
Views: 2055
Reputation: 101
I think I found the answer for your question. we should use const
when we declare df
instead of var
or let
. if you declare it using var
or let
typescript will throw an error
* "Property 'description' is missing in type '(str: string) => string' but required in type 'DescribableFunction'.ts(2741) test.ts(2, 5): 'description' is declared here." *
Upvotes: -1
Reputation: 48230
Actually, Object.assign
has a signature that returns an interection type of its arguments
Object.assign<T,U>( t: T, u: U ) : T & U
it could be then just
type DescribableFunction = {
description: string;
(str: string): string;
}
const df: DescribableFunction = Object.assign(
(str: string) => str,
{ description: 'df function description' },
);
console.log(df.description, df('hello world'));
// works
This has a drawback, it only works when you assign the description to the function and not the other way around, although TypeScript types both.
// types correctly but doesn't work (for obvious reason)
type DescribableFunction = {
description: string;
(str: string): string;
}
const df: DescribableFunction = Object.assign(
{ description: 'df function description' },
(str: string) => str,
);
console.log(df.description, df('hello world'));
// df is not a function
Upvotes: 2
Reputation: 816
There is no "literal" syntax for declaring a function with extra properties.
But functions are normal objects, and properties can be added to them:
const df: DescribableFunction = (str: string) => {
return str;
}
df.description = "df function description"
Typically, Typescript would complain that property description
is missing in the initial declartion of df
, but it looks like it makes an exception for functions, allowing them to be added later on.
As for constructor signatures, they map nicely to the class syntax. Take the following example:
type CacheableConstructor = {
new(s: string): { x: number };
cached: boolean
};
It can be implemented like this:
class SomeCC {
static cached = false
x: number
constructor(s: string) {}
}
// check that if matches the constructor signaure
const cc: CacheableConstructor = SomeCC
Upvotes: 2
Reputation: 748
I did not know this myself, but the compiler will actually check that you set the description
property after creating the function:
type DescribableFunction = {
description: string;
(str: string): string;
}
const df: DescribableFunction = (str: string) => {
return str;
}
// if you comment out the following line, the compiler will complain
df.description = 'df function description',
console.log(df.description, df('hello world'));
Upvotes: 1