Description
π Search Terms
use default value to assert generic type
default value parameters destructuring
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
It is common to give default parameters to functions :
function foo<T = null>(a: T = null) { return a; }
The issue is that this causes the following error :
Type 'null' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'null'.
Requiring us to do a quite dirty cast : null as unknown as T
.
It could be nice if TS made use of defaults parameters values (and defaults destructured parameters values) when asserting the generics types. And only raise an error when calling the function with a generic type incompatible with the default value:
function foo<T>(a: T = null) { return a; } // currently unknown, should be null.
foo<number>(); // would raise an error "generic type T=number incompatible with type of "a" default value.
I assume the issue comes from .d.ts
files where we can't write default values as they are implementation details, therefore having to write:
function foo<T>(a?: T);
// or
function foo<T = number>(a?: T);
Maybe we could introduce a new notation to explicit the type of the default values for .d.ts files ?
function foo<T>(a?number: T); // if a not given, then a (and T) are "number".
π Motivating Example
This could be quite useful when destructuring parameters:
type Opts<T, U, V, ...> = {
a: T,
b: U,
c: V
...
}
function foo<T, U, V, ...>({a = 43, c = 42, b = 43}: Opts<T,U,V,...> = {});
// with no needs for Partial<> when default values are provided, to ensure correct generic parameters assertions.
function foo<O extends Opts<...>>({a = 43, c = 42, b = 43}: O = {});
π» Use Cases
Cf explanations in suggestion.