-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Use the default value when asserting the type of a parameter #60054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
No, it just requires you to be accurate with your types: If you write |
This requires to write 3 times the same information: function foo<T = null>(a: T|null = null) { return ...; } Also, I had 2 issues in other (more complex) contexts where :
When destructuring: {
type Opts<T> = { a: T|null };
function foo<O extends Opts<T>, T = null>({a = null}: Partial<O> = {}) { return null as unknown as T }
let a = foo({a: null}); // null
let b = foo(); // null
let c = foo({a: 4}); // null
}
{
type Opts<T> = { a: T|null };
function foo<O extends Opts<T>, T>({a = null}: Partial<O> = {}) { return null as unknown as T }
let a = foo({a: null}); // unknown
let b = foo(); // unknown
let c = foo({a: 4}); // unknown
}
{
type Opts<T> = { a: T|null };
function foo<O extends Opts<unknown>>({a = null}: Partial<O> = {}) { return null as unknown as O["a"] }
let a = foo({a: null}); // null
let b = foo(); // unknown
let c = foo({a: 4}); // number
}
// other tests in the playground IIRC, doing
Which is an issue as
I could use I guess a complete workaround would be: type X2<T> = Exclude<T, any> extends never ? null : null;
type X<A, T, D> = Exclude<A, D> extends never ? D : T;
// + need to handle A = any ?
function foo<T = null>(a: T|X2<T> = null) {
return {} as unknown as X<typeof a, T, null>;
}
let a = foo(); // null
let b = foo(34); // number
let c = foo(null); // null
let x = {} as unknown as number|null;
let d = foo(x); // null|number EDIT: this may also cause issues when doing Maybe I'm missing something simple and obvious. I think that a notation to indicate the type of the default value would make things easier and more explicit. |
Duplicate of or strongly related to #58977 |
Indeed, this is strongly related. My approach wasn't really to "defer" the type check, which may explain why I didn't found it when searching for existing issues. My approach was to assume the type of the default value is the type of the generic type if no arguments are provided (and to raise an error if an incompatible generic type is explicitly provided). But, in practice, I guess this is almost the same thing. From the issue you cited:
I think my feature request provides a possible representation for .d.ts files using types instead of values.
My feature request could allow to write it as For the : declare const aa: true | undefined;
const j = x(aa); I think the behavior should depends on the TS flag (I don't remember its name) allowing or disallowing to pass If giving EDIT: This could behave a little like : function foo<T extends null>(a?: T): T
function foo<T>(a: T): T
function foo(a: unknown = null) { return a; }
let a = foo(); // null
let b = foo(43); // number
let c = foo<number>(); // number does not satisfy the constraint 'null' |
There is no such flag, it's always allowed to pass |
Indeed. I misremembered an issue I had with : function foo({a}: {a?: number} = {}) { return a; }
foo({a: undefined}); |
Maybe the function foo<T extends null>(a?: T) // or function foo<T extends typeof default_value>(a?: T)
function foo<T>(a: T)
function foo(a: unknown = null) { ... } Which would help for parameters destructuring as we'd need 2^n signature calls ? // both not given
function foo<T extends null, U extends null>({a, b}: {a?: T, b?: U})
// one given
function foo<T extends null, U>({a, b}: {a?: T, b: U})
function foo<T, U extends null>({a, b}: {a: T, b?: U})
// both given
function foo<T, U>({a: T, b: U})
function foo({a = null, b = null}: {a: unknown, b:unknown}) { ... } |
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π 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 :
The issue is that this causes the following error :
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:
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:Maybe we could introduce a new notation to explicit the type of the default values for .d.ts files ?
π Motivating Example
This could be quite useful when destructuring parameters:
π» Use Cases
Cf explanations in suggestion.
The text was updated successfully, but these errors were encountered: