🔎 Search Terms
guards
null undefined
type narrowing
generic function
type inside generic function
Searched for related issues, didn't found any.
Maybe this issue is somehow related to the type narrowing system ?
🕗 Version & Regression Information
- This is the behavior in every version I tried.
⏯ Playground Link
Playground Link
💻 Code
See playground for full example.
type Hook = (...args: any[]) => any;
export type Hooks = Record<string, Hook>;
function foo1<T extends WithHooks<any>>() {
type Hooks = GetHooks<T>; // but works if in the generic template.
const hook = {} as Hooks[keyof Hooks]; // type: GetHooks<T>[keyof GetHooks<T>]
if( hook === undefined)
return;
hook(...null as any); // nok: adds '& ({} | null)' to the type.
}
🙁 Actual behavior
Somehow TS adds & | ({}|undefined) or & | ({}|null) to my type as if it was narrowing from & ({} | undefined | null)... but where does this type would come from ???
If I test with hook === false and ! hook, the type isn't modified (cf playground). Also tested with typeof === "object", === 2, === "2", and with a personalized type guard is {}. Seems to only occurs when testing with undefined and null.
I understand that conditions sometimes breaks type narrowing, but I shouldn't have type narrowing here, right ?
🙂 Expected behavior
The type shouldn't change.
Additional information about the issue
Found this issue by accident.
Declaring a type inside a generic function isn't recommended, so this issue shouldn't have a big impact.
Still, this behavior quite surprises me, and might cause issues in other contexts (or be the cause of other strange behaviors).
Note: an easy workaround is to put the type definition inside the function generic types:
function foo5<T extends WithHooks<any>, MyHooks extends Hooks = GetHooks<T>>() {
const hook = {} as MyHooks[keyof MyHooks];
if( hook === undefined)
return;
hook(...null as any); // ok
}
🔎 Search Terms
guards
null undefined
type narrowing
generic function
type inside generic function
Searched for related issues, didn't found any.
Maybe this issue is somehow related to the type narrowing system ?
🕗 Version & Regression Information
⏯ Playground Link
Playground Link
💻 Code
See playground for full example.
🙁 Actual behavior
Somehow TS adds
& | ({}|undefined)or& | ({}|null)to my type as if it was narrowing from& ({} | undefined | null)... but where does this type would come from ???If I test with
hook === falseand! hook, the type isn't modified (cf playground). Also tested withtypeof === "object",=== 2,=== "2", and with a personalized type guardis {}. Seems to only occurs when testing withundefinedandnull.I understand that conditions sometimes breaks type narrowing, but I shouldn't have type narrowing here, right ?
🙂 Expected behavior
The type shouldn't change.
Additional information about the issue
Found this issue by accident.
Declaring a type inside a generic function isn't recommended, so this issue shouldn't have a big impact.
Still, this behavior quite surprises me, and might cause issues in other contexts (or be the cause of other strange behaviors).
Note: an easy workaround is to put the type definition inside the function generic types: