It is impossible without type assertions.
Due to historical reasons, some constructors in JavaScript can be invoked with new keyword or as a regular functions, for instance Date or Array.
These constructors are built in. You are not allowed to build such constructor without type assertions. However, you can get rid of new (someArg: number): string in DescribableFunction and just to add description property:
type DescribableFunction = {
description: string;
(arg: string): number;
};
function doSomething(fn: DescribableFunction) {
console.log(`${fn.description} returned ${fn('lorem')} or ${new fn(1)}`);
}
const fn: DescribableFunction = function (arg: string) {
return 42
}
fn.description = ''
doSomething(fn)
Here you can find more explanation about typing static property of functions.
Here you can find related question/answer
P.S.Please keep in mind that you can create custom constructor with similar behavior in pure js (see new.target)