Typescript: Force Default Generic Type to be `any` instead of `{}`
Is it possible? (Without changing the function calls obviously. AKA without a().)
Yes.
I believe in your case you would do
var a = function<T = any>() : T {
return null;
}
Generic defaults were introduced in TS 2.3.
Default types for generic type parameters have the following syntax:
TypeParameter :
BindingIdentifier Constraint? DefaultType?
DefaultType :
`=` Type
For example:
class Generic<T = string> {
private readonly list: T[] = []
add(t: T) {
this.list.push(t)
}
log() {
console.log(this.list)
}
}
const generic = new Generic()
generic.add('hello world') // Works
generic.add(4) // Error: Argument of type '4' is not assignable to parameter of type 'string'
generic.add({t: 33}) // Error: Argument of type '{ t: number; }' is not assignable to parameter of type 'string'
generic.log()
const genericAny = new Generic<any>()
// All of the following compile successfully
genericAny.add('hello world')
genericAny.add(4)
genericAny.add({t: 33})
genericAny.log()
See https://github.com/Microsoft/TypeScript/wiki/Roadmap#23-april-2017 and https://github.com/Microsoft/TypeScript/pull/13487
Is it possible? (Without changing the function calls obviously. AKA without a().)
No.
PS
Note that having a generic type that isn't actively used in any function parameters is almost always a programming error. This is because the following two are equavalent:
foo<any>()
and <someEquvalentAssertion>foo()
and leaves it completely at the mercy of the caller.
PS PS
There is an official issue requesting this feature : https://github.com/Microsoft/TypeScript/issues/2175
Taking this a little further for a slightly different application, but you can also default type arguments to another type argument.
For example, let's take:
class Foo<T1 = any, T2 = T1> {
prop1: T1;
prop2: T2;
}
and so:
const foo1 = new Foo();
typeof foo1.prop1 // any
typeof foo1.prop1 // any
const foo2 = new Foo<string>();
typeof foo2.prop1 // string
typeof foo2.prop2 // string
const foo3 = new Foo<string, number>();
typeof foo3.prop1 // string
typeof foo3.prop1 // number