Tips for creating an interface in TypeScript that prevents access to uninitialized properties of a class

Interfaces still baffle me a bit. I understand that interfaces are typically used for public properties, but I want to create an interface that will prevent access to uninitialized properties. Currently, I am able to access this.material without any errors even when it is undefined.

This is my current code:

interface ColliderConstructorArgumentInterface {
    radius: number,
    position?: THREE.Vector3
}

export interface Collider extends ColliderConstructorArgumentInterface {
    geometry: THREE.SphereGeometry
    material: THREE.MeshBasicMaterial
    mesh: THREE.Mesh
    position: THREE.Vector3
}

export class Collider {

    constructor(settings: ColliderConstructorArgumentInterface) {

        this.radius = settings.radius;
        this.position = settings.position ? settings.position : new THREE.Vector3(0, 0, 0);

        this.geometry = new THREE.SphereGeometry(this.radius, 8, 8);
        this.mesh = new THREE.Mesh(this.geometry, this.material);

        console.log(this);
    }
}

I have two interfaces - one for the class constructor arguments and another for the other class properties.

However, as you can see, I am using the property material while setting up this.mesh, even though I haven't initialized it in the constructor, and I'm not receiving any error or warning.

...

How can I modify my interfaces to receive an error message?

I want my code to be safe and clean.

...

Thank you for any suggestions!

Answer №1

if it is understood correctly, the situation arises when:

the code this.mesh = new THREE.Mesh(this.geometry, this.material);

and at that point, this.material turns out to be undefined?

It seems there are missing properties in the class provided. Perhaps some details were omitted for the sake of brevity in the question.

To address the issue, consider utilizing strict mode in Typescript, which enforces type definitions and highlights areas where variables may be undefined. Visit here for more information on strict mode

Additionally, try prefixing interfaces with a capital letter I to distinguish them easily from other types. This way you can reference interfaces without having to include "Interface" in the name.

In the code snippet provided, the redundant position field has been removed from the ICollider interface as it inherits the property from another interface.

An implements clause has been added to the class definition to explicitly state its adherence to the defined interface.

The required properties are now declared within the class according to the implemented interface. However, not all properties are initialized with values yet.

interface IColliderConstructorArgument {
  radius:number,
  position?:THREE.Vector3
}

export interface ICollider extends IColliderConstructorArgument {
  geometry:THREE.SphereGeometry
  material:THREE.MeshBasicMaterial
  mesh:THREE.Mesh
}

export class Collider implements ICollider {

  geometry: THREE.SphereGeometry;
  material: THREE.MeshBasicMaterial;
  mesh: THREE.Mesh;
  position: THREE.Vector3;
  radius: number;

  constructor(settings: IColliderConstructorArgument) {

      this.radius = settings.radius;
      this.position = settings.position ? settings.position : new THREE.Vector3(0,0,0);

      this.geometry = new THREE.SphereGeometry(this.radius, 8, 8);
      this.mesh = new THREE.Mesh(this.geometry, this.material);

      console.log(this);
  }
  
}

To address the issue with this.material, ensure to assign a value to it. Enabling strict mode should prevent such issues in the future. This might have been the root cause of the problem previously.

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

Gain insights on Stripe Webhooks with Firebase Functions and Node.js

I've been struggling to integrate Firebase functions with Stripe webhooks for listening to events. Take a look at my code: exports.stripeEvents = functions.https.onRequest((request, response) => { try { const stripeSignature = request. ...

Initial values of dual knob settings on Ionic Range and their ability to update dynamically

As someone new to using Ionic and TypeScript, I am facing challenges in setting initial values for my Ionic Range component (V5). Referring to other posts, it seems that there are upper and lower properties within ngModel, but I'm unsure about the bes ...

Tips for setting values to the child component property in Angular 4

When I was using ngif, I encountered an issue with getting the element reference of the child component. After extensive searching, I discovered that in order to access the element, I needed to use view children instead of view child. While I am able to ge ...

All authentication logic in Angular encapsulated within the service

I am considering moving all the business logic into the auth service and simply calling the method on the component side. Since none of my functions return anything, I wonder if it's okay or if they will hang. COMPONENT credentials: Credentials = ...

What kind of output should a Server Side Component generate?

Recently, I decided to incorporate the NextPage type from Next.js into my component writing routine after hearing it's a beneficial practice. However, I discovered that it only functions properly with client-side components. When attempting to utilize ...

Angular jsonp.get request was denied despite receiving a status code of 200 indicating success

I have been attempting to access my basic web API created in Jersey, which returns the following data: [ { "id": 1, "name": "Facebook", "userName": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f4 ...

Using Higher Order Components (HOC) in combination with Redux compose and Typescript

I am trying to leverage two Higher Order Components (HOC) with Redux compose, but the compiler is not generating the correct types. The Compose function is defined in the Redux source code here source code. To better understand how the code works, you ca ...

Error in Jest Testing: An unexpected character '@' was encountered

Encountering issues with NuxtJS Jest tests and attempting to build a Nuxt app to test URL's due to route name errors in some components. Here is the code snippet I tried: beforeAll(async () => { nuxt = new Nuxt({ ...config, server: { port: 3001 } ...

Utilizing custom types in React with TypeScript and Prop-Types

Currently, I am working with a string type literal that looks like this: type MyType = 'str1' | 'str2' | 'str3'. I need one of my props to only accept this specific type, but I'm struggling to specify this in PropTypes. ...

Are there more efficient methods for locating a particular item within an array based on its name?

While I know that using a loop can achieve this functionality, I am curious if there is a built-in function that can provide the same outcome as my code below: const openExerciseListModal = (index:number) =>{ let selectedValue = selectedItems[index]; it ...

Issue with importing and exporting external types causing failures in Jest unit tests for Vue 2

I am in the process of creating a package that will contain various types, enums, consts, and interfaces that I frequently use across different projects. To achieve this, I have set up a main.ts file where I have consolidated all the exports and specified ...

TypeScript's Awaitable concept

Lately, I have been utilizing async / await functions quite frequently in my JavaScript projects. As I make the transition to TypeScript, I am gradually converting some sections of my code bases. In certain scenarios, my functions require a function as an ...

Encountering the issue of receiving "undefined" when utilizing the http .get() method for the first time in Angular 2

When working in Angular, I am attempting to extract data from an endpoint. Below is the service code: export class VideosService { result; constructor(private http: Http, public router: Router) { } getVideos() { this.http.get('http://local ...

Using the HTTP Post method to retrieve a file object: a step-by-step guide

Is there a way to utilize a http POST request in order to retrieve a file object? Though the uploading of files to the server using the POST request seems successful and flawless, attempting to fetch the file results in an unusual response: console output ...

What are the steps for integrating Socket.IO into NUXT 3?

I am in search of a solution to integrate Socket.IO with my Nuxt 3 application. My requirement is for the Nuxt app and the Socket.IO server to operate on the same port, and for the Socket.IO server to automatically initiate as soon as the Nuxt app is ready ...

An error has occurred in the Next.js App: createContext function is not defined

While developing a Next.js application, I keep encountering the same error message TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function every time I try to run my app using npm run dev. This issue arises when attempting to co ...

Mixing a static class factory method with an instance method: a guide

After introducing an instance method addField in the code snippet below, I encountered an issue with the Typescript compiler flagging errors related to the static factory methods withError and withSuccess: The error message states: 'Property ' ...

Exploring the Concept of Dependency Injection in Angular 2

Below is a code snippet showcasing Angular 2/Typescript integration: @Component({ ... : ... providers: [MyService] }) export class MyComponent{ constructor(private _myService : MyService){ } someFunction(){ this._mySer ...

Subclass method overloading in Typescript

Take a look at this example: class A { method(): void {} } class B extends A { method(a: number, b: string): void {} } An error occurs when trying to implement method() in class B. My goal is to achieve the following functionality: var b: B; b.met ...

Run JavaScript code whenever the table is modified

I have a dynamic table that loads data asynchronously, and I am looking for a way to trigger a function every time the content of the table changes - whether it's new data being added or modifications to existing data. Is there a method to achieve th ...