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'));
CodePudding user response:
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
CodePudding user response:
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
CodePudding user response:
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'));