Limit the usage of typescript to ensure that references to properties of 'any' object are verified

I'm facing a situation where I have a JS object called myObject, and it is of type any. Unfortunately, I cannot change the type as it's coming from a library.

The issue I encounter is that when trying to access a property from myObject, TypeScript does not throw any errors since its type is any. However, there is a possibility that myObject could be undefined, leading to a crash.

Is there a way to make TypeScript generate an error in such cases?

For instance:

console.log(myObject.myProperty) // <-- this will cause a crash if myObject is undefined.

What I desire:

console.log(myObject.myProperty) // <-- TypeScript shows error
console.log(myObject?.myProperty) // <-- TypeScript doesn't show error

Is there a tsconfig setting to modify this behavior?


I'm specifically not interested in using type unknown for resolving this.

Answer №1

Unfortunately, TypeScript does not offer support for a stricter interpretation of the `any` type where member access is restricted unless it is deemed safe. There hasn't been any formal request for this feature either. While there was a proposal for `--strictAny`, it was eventually closed in microsoft/TypeScript#24737, with the reason being that adding extra complexity to the `any` type didn't seem warranted, especially given that `any` is often used intentionally to disable type checking in certain real-world scenarios.

Instead of waiting for TypeScript to introduce such functionality, you could consider utilizing a linter like TypeScript ESLint. The `no-unsafe-member-access` rule specifically prohibits unsafe member access on variables typed as `any`. However, be aware that this may lead to unwanted errors even in situations where proper type checking has been implemented, making it more restrictive than desired.

declare const myObject: any;
myObject.myProperty // warning: unsafe access 😊
myObject?.myProperty // warning: unsafe access ☹

If you find yourself in this situation, one workaround could involve copying the value to a variable of a non-`any` type:

type MyAny = { [k: string]: any } | undefined | null;
const _myObject: MyAny = myObject
_myObject.myProperty; // error
_myObject?.myProperty; // okay

Alternatively, you could create a type checking function to narrow down the `any` type to a more safely indexable type:

function nonNullish(x: any): x is { [k: string]: any } {
  return x != null;
}
if (nonNullish(myObject)) {
  myObject.myProperty // okay
}

Another approach could involve discussing with the typings provider for the library to emphasize that using `any` might be too loose of a type, especially if the value could potentially be `undefined` or `null` at runtime. If that's not an option, then perhaps accepting and monitoring potential issues until they actually occur might be the way to go.

TS-ESLint Playground link to code

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

Develop a FormGroup through the implementation of a reusable component structure

I am in need of creating multiple FormGroups with the same definition. To achieve this, I have set up a constant variable with the following structure: export const predefinedFormGroup = { 'field1': new FormControl(null, [Validators.required]) ...

When passing an invalid value to the Props in TypeScript, no errors are being thrown

const enum ColumnValues { one = 1, two = 2, three = 3, } interface Props { style?: StyleProp<ViewStyle>; title?: string; titleContainerStyle?: StyleProp<ViewStyle>; titleStyle?: StyleProp<TextStyle>; textInputStyle?: Styl ...

Utilizing Angular 16 to Link Component Input with Parent Route Parameter

Picture a scenario where there is a component (some.component.ts) in Angular 16 that retrieves the value for its foo property from activeRoute, specifically from the parent route. Take a look at the code snippet below: @Input() foo!: string; constructor(p ...

Encountering an issue with d3 Angular 2 pie chart related to d3.arc data

I encountered a problem with my code: 'PieArcDatum' is not assignable to parameter of type 'DefaultArcObject.' at this specific line Argument of type return "translate(" + labelArc.centroid(d) + ")";. Could someone please assist me in ...

A new issue arises after merging in Google Datastore, as an unexpected property is

Currently, I am working on developing an API in Typescript to interact with a Google Cloud Datastore instance for storing and retrieving entities. So far, I have successfully implemented the GET, POST, and DELETE methods. However, I encountered an issue w ...

Adjust the background color of a list item using Typescript

At the top of my page, there's a question followed by a list of answers and the option to add new ones. You can see an example in the image below. https://i.stack.imgur.com/NPVh7.jpg The format for each answer is "(username)'s response: at this ...

A guide on retrieving data from Firestore using TypeScript

I've been diving into a chat project using Angular, and Firestore has given me a bit of trouble. Trying to get the hang of typescript while working with it. Within app.module.ts, kicking things off with: import { provideFirebaseApp, getApp, initi ...

The editor is locked and choices are displayed in a vertical orientation

I'm currently experimenting with using draft js in my project to create a wysiwyg editor. However, I've encountered an issue where the editor appears vertically instead of horizontally when I load the component. Any idea why this might be happen ...

Incorporate JavaScript Library into StencilJs Using TypeScript

Recently, I decided to incorporate a JavaScript library called Particles.js into my project. The process involved importing it and initializing it within my component: import { Component, h } from '@stencil/core'; import * as particlesJS from &a ...

How to efficiently eliminate multiple entries with SREM in ioredis?

I am curious about the proper syntax for removing multiple entries using the SREM command. When I try this: const myKey = "myKey"; const entriesToRemove: string[] = ... this.redisClient.srem(myKey, entriesToRemove); I end up with: ReplyError: ...

How can I customize a Vue component slot in Storybook 8.0.6 using Vue 3.4 and Typescript to display various subcomponents within a story?

Incorporating a variety of sub-components into my Vue 3 component based on context is proving to be a challenge. Utilizing slots seems to be the solution in Vue 3, but I'm struggling to make it work within Storybook 8, which I'm using to showcase ...

Angular 7 error: Form control with name property does not have a valid value accessor

Currently, I am utilizing angular 7 and have a parent and child component set up as demonstrated in the Stackblitz link provided below. Strangely enough, when I assign the formControlName from the child component using "id", everything functions flawlessly ...

Angular promise not triggering loop creation

I am encountering an issue with a particular function handleFileInput(file: any) { let promise = new Promise((resolve, reject) => { this.uploadFileDetails.push({ filename:this.FileName,filetype:this.FileType}); ... resolve(dat ...

Using Typescript to create a generic return type that is determined by the type of a property within an object union

Consider the following scenario: type Setting = { key: "option_one", value: number, } | { key: "option_two", value: string, } export type SettingKey = Setting["key"]; // "option_one"|"option_two ...

What is the best way to optimize a search for objects with extensive field arrays?

Recently, I've been working with an object schema that includes an array field to store ids for objects from a separate collection. This array has the potential to contain thousands of ids. Up until now, I have been excluding this field using .select( ...

React Router is used to render routes that do not match the specified path

I am utilizing TypeScript in React Router. I have defined two routes: / and /pages/id. class MyComponent extends React.Component { render() { return <BrowserRouter> <div> <Route exact path='/' ch ...

Change validators dynamically according to conditions

Scenario: At the start, there is a single text box named Name1, a date picker called DOB1, and a check box labeled Compare. Both Name1 and DOB1 are mandatory. When the checkbox is clicked, two new form controls are dynamically included, named Name2 and DO ...

Troubleshooting compilation issues when using RxJS with TypeScript

Having trouble resolving tsc errors in the code snippet below. This code is using rxjs 5.0.3 with tsc 2.1.5 import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import 'rxjs/Rx'; let subject ...

Saving in prettier differs from running it with npm

./file.ts (INCORRECT) import { jwtGroupClaimToRolesDomain, ScopeIds } from '@invison/shared'; import { Injectable, NestMiddleware } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Response } fro ...

Having trouble sending an email using nodejs and mailgun

Before accusing me of asking a duplicate question, I want to clarify that I have already searched for solutions and none of them worked for me. For example, I tried the solution provided in this link: Example of the domain name for mailgun before nodejs? ...