Search code examples
typescriptnull

Enforce generic type parameter to be T or null


Enforce generic function parameter to be T | null, so only values with types that include T | null can be passed:

function foo<T>(val: T) { ... }
let fooNonNull: string = "foo"
foo(fooNonNull) // should not compile because string cannot be null
let fooNull: string | null = "foo";
foo(fooNull) // should compile

Solution

  • Checking whether the union T | null extends the type T seems to create the required behavior:

    type Null<T> = T | null extends T ? T : never; 
    
    function foo<T>(val: Null<T>) { console.log(val); }
    
    let fooNonNull: string = "foo"
    foo(fooNonNull); // Error
    
    let fooNull: string | null = Math.random() > .5 ? "foo" : null;
    foo(fooNull) // OK
    

    Note that I had to include a random factor into the initialization of the fooNull variable to prevent TypeScript from eagerly narrowing the parameter to string.