Is it advisable to flag non-(null|undefined)able type arguments as a type error?

Can the function throwIfMissing be modified to only flag test1 as a compiler error?

function throwIfMissing<T>(x: T): T {
    if (x === null || x === undefined) {
        throw new Error('Throwing because a variable was null or undefined')
    }
    return x;
}

type Foo = string

// should error:
function test1(x: Foo): Foo {
    return throwIfMissing(x);
}

// should NOT error:
function test2(x: Foo | null): Foo {
    return throwIfMissing(x);
}

function test3(x: Foo | undefined): Foo {
    return throwIfMissing(x);
}

function test4(x: Foo | null | undefined): Foo {
    return throwIfMissing(x);
}

Note on solving an "x/y problem": this function serves as a temporary solution for transitioning a codebase's strictNullChecks setting to true. As we gradually remove the ... | null | undefined types, we aim to make unnecessary function calls trigger a compiler error.

I have experimented with using techniques like conditional types, but have not achieved success yet.

Answer №1

When the option strictNullChecks is enabled, a conditional type can be utilized to determine if the provided parameter T includes either null or undefined. Additionally, an intersection type can be used to prevent passing in parameters that contain these values, making it more challenging for the function to execute.

type ErrorIfNotNUllOrUndefined<T, TMessage> = (null extends T ? T : undefined extends T ? T  : TMessage);
function throwIfMissing<T>(x: T & ErrorIfNotNUllOrUndefined<T, "Parameter can't be null don't check">):Exclude<T, null | undefined> {
    if (x === null || x === undefined) {
        throw new Error('Throwing because a variable was null or undefined')
    }
    return x as any;
}

type Foo = string
type dd = (null extends Foo | null ? {} : "Error")
// this is an error 
function test1(x: Foo): Foo {
    return throwIfMissing(x); //Argument of type 'string' is not assignable to parameter of type '"Parameter can't be null don't check"'.
}

// all ok 
function test2(x: Foo | null): Foo {
    return throwIfMissing(x);
}

function test3(x: Foo | undefined): Foo {
    return throwIfMissing(x);
}

function test4(x: Foo | null | undefined): Foo {
    return throwIfMissing(x);
}

If strictNullChecks is disabled, there is no clear distinction between a simple string and a string | null | undefined.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Getting the PlayerId after a user subscribes in OneSignal with Ionic2

Currently working on an app with Ionic2 and facing a challenge with retrieving the player id after a user subscribes in order to store it in my database. Any suggestions on how I can retrieve the unique player id of OneSignal users post-subscription? ...

Can someone explain how to implement document.querySelector in TypeScript within the Angular framework?

I am tackling the task of creating a login/register form that allows users to switch between the two forms with the click of a button. The goal is to only display one form at a time. Initially, I implemented this functionality in a basic HTML file and it w ...

Exploring the Power of Chained Promise Calls

Afterwards, in the .then section, I call another promise for an HTTP request: .then(result => { this.service().then(data => {}); }); Would you say that using chained promises in this manner is correct? ...

Is there a program available that can efficiently convert or translate JSON objects into TypeScript types or interfaces?

Can anyone recommend a tool that can easily convert a JSON object into a TypeScript type or interface? An example input would be something like this: I'm hoping to paste the JSON object into the tool and receive an output structure similar to: expor ...

Error: zsh is unable to locate the command, even after defining it in package.json bin and installing it globally

I attempted to create a command-line application using TypeScript. Below is the code I have written: //package.json { "name": "jihea-cli", "version": "1.0.0", "description": "", "main": "index.ts", "bin": { "cli": "./bin/index.ts" }, // ...

Angular 8: Implementing Form Validation with a Boolean Flag

Within my HTML code, I have a function (change)="limitUser($event)". In Typescript, I utilize a for loop to iterate through each element and determine if the value is less than 10. If it exceeds 10, the inValid = true condition is set. All form fields in m ...

Resolving Hot-Reload Problems in Angular Application Following Upgrade from Previous Version to 17

Since upgrading to Angular version 17, the hot-reload functionality has been causing some issues. Despite saving code changes, the updates are not being reflected in the application as expected, which is disrupting the development process. I am seeking ass ...

Implement conditional props for a React component by linking them to existing props

In my current project, I am working on a component that has a loading state. The component has an isLoading prop which determines whether the component is currently in a loading state or not: interface CustomImageComponentProps { isLoading: boolean ...

Determine the output type of a function in Typescript using an input value specified by an enum

I am currently saving settings to local storage and want to be able to input responses when retrieving (and possibly inserting) values from/to the storage. After researching, it seems that using function overloading is the best approach. Here is what I ha ...

Retrieve the time zone setting from either my browser or server, and then incorporate it into angular2-highcharts

My current timezone setup is done manually using the timezoneOffset function from the Highcharts API. I am currently in GMT+2 so I set it to -2 * 60. However, I encountered an issue where my setup would not work properly when the hour changes in October. T ...

Tips for exporting and reusing third-party types in TypeScript

I am facing a challenge with my package, which relies on a 3rd party package API for most of its functions. How can I export the types from the 3rd party package API in my own package? For instance: React uses @types/react to define its types Let's ...

There is a Typescript error stating that the argument of type 'NodeListOf<HTMLInputElement> | undefined' cannot be assigned to the parameter of type 'Iterable<HTMLInputElement> ...'

While working on my React/Typescript App, I encountered an issue when trying to access an array of inputs in an event listener using 'e.currentTarget'. To solve this, I utilized Array.from() to convert the NodeListOf into an array and ensured tha ...

Improving the management of user input in Lit components

I am seeking a more efficient method to manage all inputs within my lit component while minimizing the code usage. I am also employing Typescript in this process, utilizing @change=${this.handleInput} for all input fields. Below is an example of how the ha ...

How can I retrieve an array from an object containing both a property and an array in TypeScript?

One of my objects always consists of a property and an array. When I use the console.log(obj) method to print it out, it looks like the following example: ProjectName: MyTest1 [0] { foo: 1, bar: 2} [1] { foo: 3, bar: 4} [2] { foo: 5, bar: 6} Alternat ...

When I utilize a component to create forms, the React component does not refresh itself

One of the components I am working with is a form handling component: import React, { useState } from "react"; export const useForm = (callback: any, initialState = {}) => { const [values, setValues] = useState(initialState); const onCha ...

Retrieving the input[text] value in TypeScript before trimming any special characters

One of the tasks I am working on involves a form where users can input text that may contain special characters such as \n, \t, and so on. My objective is to replace these special characters and then update the value of the input field accordingl ...

Angular - creating a specialized input field for a unique MatDialogConfig configuration file

I have a unique setup with a custom MaterialDialogConfig file dedicated to handling all of my material dialog components. Here's what the configuration file looks like: import { MatDialogConfig } from "@angular/material"; export class MaterialDialog ...

Creating Versatile Functions for HttpClient Wrapping

Scenario: In my set of services, I find myself repeatedly writing code for data calls which results in a lot of duplicated code. To streamline the process and reduce redundancy, I am looking to implement a wrapper function: All these functions essentiall ...

Issue: Pipe 'AsyncPipe' received an invalid argument '[object Object]'

I’m encountering an issue while attempting to replicate the steps from a specific YouTube tutorial. At the 8:22 mark of this video, I’m facing the following error: Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe&apos ...

What is the best way to monitor updates made to a function that utilizes firestore's onSnapShot method?

I am currently working with the following function: public GetExercisePosts(user: User): ExercisePost[] { const exercisePosts = new Array<ExercisePost>(); firebase.firestore().collection('exercise-posts').where('created-by&apo ...