Skip to content

Use the default value when asserting the type of a parameterΒ #60054

Closed as not planned
@denis-migdal

Description

@denis-migdal

πŸ” Search Terms

use default value to assert generic type
default value parameters destructuring

βœ… Viability Checklist

⭐ 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions