What is the best approach for defining variables in typescript?

Let's talk about creating a variable for a car:

export class ICar {
  wheels: number;
  color: string;
  type: string;
}

So, which way is better to create the variable?

Option one:

const car = {
  wheels: 4,
  color: 'red',
  type: 'truck'
} as ICar;

Or maybe option two:

var car = new ICar(); 
car.wheels = 4; 
car.color = 'red'; 
car.type = 'truck'; 

Answer №1

If ICar is defined as a class, then the initial example provided is indeed incorrect.

To elaborate on the example given, let's consider the following:

export class ICar {
    wheels: number;
    color: string;
    type: string;

    constructor() {
        this.wheels = 2;
        this.color = 'blue';
        this.type = 'motorcycle'
    }

    drive() {
        console.log('Driving!')
    }
}

The proper way to create an instance of a class is by using the new keyword.

// Correct approach
var car1 = new ICar(); 
car1.wheels = 4; 
car1.color = 'red'; 
car1.type = 'truck'; 
car1.drive() // Executed successfully

It is important to note the significance of the last line car1.drive(), which only works because the class was instantiated.

On the other hand, if we attempt a similar process with a typecast:

// Not recommended
const car2 = {
    wheels: 4,
    color: 'red',
    type: 'truck'
} as ICar;
car2.drive() // Error at runtime

Subsequently, invoking car2.drive() results in a runtime error since the method does not exist within that context. This issue arises because the use of as ICar does not actually transform the object into an instance of ICar; it solely informs Typescript to treat the value differently without altering its nature.

Hence, employing as in such scenarios introduces bugs that could have been caught by Typescript.

Interactive playground with code snippet.

Answer №2

By experimenting with it in the TypeScript Playground, you'll discover that your code doesn't compile as expected.

An interface might be more suitable than a class. An interface defines the structure an object should have, while a class includes contructor(), methods, and unnecessary elements. Here's how I would approach your scenario:

// Define an interface to describe the characteristics of a car
export interface ICar {
  wheels: number;
  color: string;
  type: string;
}

// Create a variable following the ICar interface,
// and assign it a valid object
const car1: ICar = {
  wheels: 4,
  color: 'red',
  type: 'truck'
};

Answer №3

It is advisable to opt for the second option

var vehicle = {}; 
vehicle.wheels = 4; 
vehicle.color = 'red'; 
vehicle.type = 'truck'; 

The initial object is defined using const, making it immutable. Therefore, selecting the first choice would be more appropriate.

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

What is the best method to include spacing between strings in an array and then combine them into a csv-friendly format?

The method I am currently employing involves the following: var authorsNameList = authors.map(x => x.FirstName + ' ' + x.LastName); Yet, this generates an outcome similar to this: Bob Smith,Bill Jones,Nancy Smith Nevertheless, the desired ...

What is the reason why the swiper feature is malfunctioning in my React-Vite-TS application?

I encountered an issue when trying to implement Swiper in my React-TS project. The error message reads as follows: SyntaxError: The requested module '/node_modules/.vite/deps/swiper.js?t=1708357087313&v=044557b7' does not provide an export na ...

Is it possible for prettier to substitute var with let?

One of the tools I utilize to automatically format my Typescript code is prettier. My goal is to find out if there is a way to have prettier replace all instances of 'var' with 'let' during the formatting process. Below is the script I ...

What could be causing this TypeError to appear in my Angular unit testing?

this.columnDefs.forEach((columnDef) => { columnDef.floatingFilter = this.hasFloatingFilter; }); this.gridApi.setColumnDefs(this.columnDefs); ERROR: 'ERROR', TypeError: this.gridApi.setColumnDefs is not a function TypeError: this.gridApi.set ...

The Mui datepicker displays the day and month in reverse order

Do you have trouble with date search filter using the mui datepicker component? It seems that when entering a date in the input and clicking on search, the day gets swapped with the month. For instance, if you input 03/05/2022, it returns Sat Mar 05 2022 ...

Creating a digital collection using Vue, Typescript, and Webpack

A short while back, I made the decision to transform my Vue project into a library in order to make it easier to reuse the components across different projects. Following some guidelines, I successfully converted the project into a library. However, when ...

I am looking to extract solely the numerical values

Programming Tools ・ react ・ typescript ・ yarn I am trying to extract only numbers using the match method But I keep encountering an error Error Message: TypeError: Cannot read property 'match' of undefined const age="19 years ...

Exporting a Middleware member is essential for defining Koa middleware type definitions

Currently utilizing KoA with Typescript and incorporating the KoA middleware KoA-static and KoA-bodyparser. Ensuring that I have installed the type definition packages @types/koa, @types/koa-bodyparser, and @types/koa-static. However, upon running tsc, enc ...

What is the best way to set a fixed width for my HTML elements?

I am facing an issue with my user registration form where error messages are causing all elements to become wider when they fail validation. I need help in preventing this widening effect. How can I achieve that? The expansion seems to be triggered by the ...

Angular8: Adjusting Activity Status After Leaving Page

When performing activities like upload, download, delete, and edit, I display statuses such as 'upload started' or 'upload completed'. This works perfectly when staying on the same page. However, there are instances where a user may nav ...

Unable to upload file in angular2 due to empty Body (FormData)

Attempting to upload a photo with Angular2 to my REST Service (Loopback). The Loopback service has been successfully tested using Postman and is able to accept files with the x-www-form-urlencoded header. Below is a simplified version of the service metho ...

Unable to determine the data type of the property within the table object

Is it feasible to retrieve the type of object property when that object is nested within a table structure? Take a look at this playground. function table<ROW extends object, K extends Extract<keyof ROW, string>>({ columns, data, }: { col ...

Eliminating tail recursion for conditional types is ineffective

In TypeScript version 4.5, the feature of tail call optimization was introduced for recursive generics. The code snippet below calculates Fibonacci numbers (in unary) up to F12, but encounters an error when trying to compute F13 due to the "Type instantiat ...

A guide on incorporating and utilizing third-party Cordova plugins in Ionic 5

Attempting to implement this plugin in my Ionic 5 application: https://www.npmjs.com/package/cordova-plugin-k-nfc-acr122u I have added the plugin using cordova plugin add cordova-plugin-k-nfc-acr122u but I am unsure of how to use it. The plugin declares: ...

Can an enum be declared in Typescript without specifying a type explicitly?

Within an interface, I have a group of 10+ (optional) members, most of which have a specific set of potential values. To streamline this, I would like to utilize enums. However, creating separate enum types for each member (which are only used once and hav ...

Is it possible to access your app directly from the browser without requiring any user prompts?

After successfully setting up my app for both android and ios with the necessary app link and universal link, I am now focusing on redirecting users from a specific website to my app. The mobile aspect is all set, but I need to work on the browser/server s ...

the Sprite fails to appear on the screen

Can you help me figure out how to fix the issue I'm having with loading images in this component? Currently, when I refresh the page, the image does not load properly and appears resized to 1 pixel width. Should I wait for the image to fully load befo ...

What is the process for connecting a form to a model in Angular 6 using reactive forms?

In the time before angular 6, my approach involved utilizing [(ngModel)] to establish a direct binding between my form field and the model. However, this method is now considered deprecated (unusable with reactive forms) and I find myself at a loss on how ...

Unable to find the <a> element with a numerical id attribute in Playwright. The selector '#56' is not recognized as valid

Seeking to identify and target the <a> element with an id attribute. Attributes that may be used: role href title id style onclick I am able to do so using role and name, but unsuccessful with id or onclick. The latter two would be beneficial for f ...

Turn TypeScript - Modify type properties to reflect types of their descendants

I am currently working on creating a type that will modify a generic type based on its children. To provide some clarity, I have created a simplified example below: Original type type FormFields = { username: { type: string, ...