Setting a default value for a data type within Typescript

My goal is to set default values for all properties in my custom type if they are not defined.

This is what I have done:

// custom type with optional properties
type MyType = {
  // an example property:
  str?: string
}
// with numerous properties, assigning them individually is not feasible
// hence, default values object was created
const defaultValuesForMyType: MyType = {
  str: "hello world!"
}

// function that performs actions with a string input
function doThingsWithString(str: string): void {
  console.log(str);
}

// function that takes an object of custom type as input
function driver(inputObject: MyType) {
  const finalObject: MyType = { ...defaultValuesForMyType, ...inputObject };
  doThingsWithString(finalObject.str);
}

However, VS Code displays the error:

doThingsWithString(finalObject.str);
                   ^~~~~~~~~~~~~~^
Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'. ts(2345)
const finalObject: {
    str?: string | undefined;
}

I believed that finalObject cannot be undefined, right? 🤔

edited:

@jcalz's solution did the trick!

I realized it was a class issue, my mistake 😅

// my custom type with all optional properties
type MyType = {
  // an example property:
  str?: string
}
// imagine I have hundreds of properties, I can't assign all of them one by one
// so I created a object for default values
const defaultValuesForMyType = {
  str: "hello world!"
}

// passes a string to do something
// imagine it's a function in other API that I can't change
function doThingsWithString(str: string): void {
  // do something, doesn't matter, for example:
  console.log(str);
}

class TestClass {
  propObject;

  driver(inputObject: MyType) {
    this.propObject = { ...defaultValuesForMyType, ...inputObject };
    doThingsWithString(this.propObject.str);
  }
}

No error, but VS Code now indicates that TestClass#propObject is of type any

Answer â„–1

You've specified the type of defaultValuesForMyType as MyType, which means that's all the compiler knows about it. Any specific information from the initializing object literal is lost, and the str property is optional. This allows you to remove the str property using delete, hence indicating why such an annotation might be used. From the compiler's perspective, str could either be a string or

undefined.</p>
<p>If you want the compiler to understand that the <code>str
property is always a string and never
undefined</code, then it's better not to annotate at all. Let the compiler infer its type for you:</p>
<pre><code>const defaultValuesForMyType = {
    str: "hello world!"
}
/* const defaultValuesForMyType: {
    str: string;
} */

Following this, by spreading defaultValuesForMyType and a MyType into a new object, the compiler will recognize a definite string value for the str property:

function driver(inputObject: MyType) {
    const finalObject = { ...defaultValuesForMyType, ...inputObject };
    // const finalObject: {  str: string; }
    doThingsWithString(finalObject.str); // okay
}

To implement this within a class, ensure you annotate the type of your field. Since it's not initialized in the constructor, it should probably be made optional:

class TestClass {
    propObject?: Required<MyType>; // annotate

    driver(inputObject: MyType) {
        this.propObject = { ...defaultValuesForMyType, ...inputObject };
        doThingsWithString(this.propObject.str);
    }
}

Note that I used Required<MyType> to express the relevant type, using the Required utility type to generate a version of MyType where all properties are required. You could also use {str: string}, but for scalability, Required<MyType> may be a better choice if there are many properties.

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

Error: Unexpected token < occurs when using SVG require in Jest

I'm struggling to locate the source of this error. Currently, I am working with Typescript in React and using Jest and Enzyme for unit testing. Below is a snippet from my Package.json file: "scripts": { "start": "node server.js", "bundle": ...

Container that displays vertical scroll while permitting floating overflows

Is there a way to set up a container so that when the window size is too small, it displays a scroll bar to view all elements that don't fit in one go? At the same time, can the child containing floating elements be allowed to extend beyond the bounda ...

Angular2 authguards encountering issues when trying to run asynchronous functions

I need a way to safeguard my routes by verifying if a user is logged in from the server, but I'm facing issues with asynchronous functions not executing properly. Below is the code snippet that's causing trouble: canActivate (route: ActivatedRo ...

The ViewChild from NgbModalModule in @ng-bootstrap/ng-bootstrap for Angular 6 is causing the modal to return as

I have successfully integrated ng bootstrap into my project, specifically utilizing the modal module to display a contact form. The form includes input fields for email and message, as well as a submit button. You can find the ngbootstrap module I am using ...

What is preventing me from retrieving a value from a member function or method within a TypeScript class instance?

I am facing an issue with the FileInfo class that implements the IFileInfo interface. This class has an instance member function ext and a function getExt(). Within my component, there is a private method named openTempFolder() which makes an HTTP call to ...

The configuration file tsconfig.json did not contain any input

After downloading angular2-highcharts through npm for my application, I encountered an error in the tsconfig.json file of the package while using Visual Studio Code: file: 'file:///c%3A/pdws-view-v2/node_modules/angular2-highcharts/tsconfig.json&apos ...

Developing a Universal Type in Typescript

Encountered an issue with generic types while working on a user-defined type(interface) structured like this: IList1: { prop1: string, prop2: number, prop3: string . . . } ILi ...

Dealing with Angular 2's Http Map and Subscribe Problem

Looking to parse a JSON file and create a settingsProvider. This is how I am attempting it: import {Http} from "angular2/http"; import {Injectable} from "angular2/core"; @Injectable() export class SettingsProvider{ url: string = ""; constructor ...

Creating pagination functionality for a React Material table

Check out this Spring Boot endpoint that I use for retrieving items from the database: import React, { useEffect, useState } from "react"; // Additional imports export default function BusinessCustomersTable() { // Functionality and code impl ...

What is the method for assigning a string to module variable definitions?

As someone new to TypeScript and MVC, I find myself unsure if I am even asking the right questions. I have multiple TypeScript files with identical functionality that are used across various search screens. My goal is to consolidate these into a single fil ...

JavaScript module declarations in TypeScript

Recently, I delved into the world of a Node library known as bpmn-js (npmjs.com). This library is coded in JavaScript and I wanted to incorporate typings, which led me to explore d.ts files. My folder structure looks like this webapp @types bpmn ...

I am encountering an issue regarding the 'endpoint' property within my environment.ts file while working on an Angular 17 project

My goal is to incorporate the property endpoint from my environment.ts file into my service: export const environment = { production: false, endpoint: 'http://localhost:3000/api/cabin/' }; This snippet showcases my service: import {Injectabl ...

What are the steps to incorporating a personalized component into an extension?

I am working on a TypeScript file that includes a class inheriting cc.Component. My goal is to package this file as an extension and make it easily accessible within the editor, allowing users to add it to a node with ease. What steps should I take to ac ...

Troubles encountered while trying to make MediaRecorder function in Angular 9

Recently, I've been working on integrating Media Recorder into my Angular 9 application by following the instructions provided at this link. However, I have encountered some issues along the way. When I access the page with the Media Recorder compone ...

How to make an input blur in Angular 2 when a button is clicked?

Is there a way to blur an input field by pressing the return button on a mobile native keyboard? Here is an example: <input type="text" #search> this.search.blur() //-- unfocus and hide keyboard ...

Exploring Angular 8: Connecting elements to an array filled with objects

My goal is to achieve the following: https://i.sstatic.net/TQeKN.png In my form, I have 2 fields: description and price. When the plus button is clicked, additional input fields (Input 2 and Price 2) are generated dynamically. I want to bind these field ...

acquire tabulations from every single document within the templates on DocuSign

When using Docusign, it is possible to retrieve tabs data for a specific document within a template by specifying the documentId. However, I have not been able to locate a method to obtain tabs data for all documents contained within a template. ...

The object prototype can only be an instance of an Object or null; any other value will

While attempting to create a codesandbox in order to replicate a bug, I encountered an additional issue. You can view my codesandbox here: https://codesandbox.io/s/vue-typescript-example-o7xsv The error message states: Object prototype may only be an ...

What are some ways to utilize TypeScript in incorporating extensions to `koa.Request` packages?

Struggling to utilize both koa-tree-router and koa-bodyparser simultaneously, encountering persistent TypeScript errors: export const userLoggingRouter = new KoaTreeRouter<any, DefaultContext>(); userLoggingRouter.post('/logs/action', (ctx ...

transformation of categorized unions in software development

Experimenting with routing-controllers and its built-in class-transformer feature, I tried creating an interface for executing a search query based on either a location id or location coordinate. My aim was to utilize a discriminated union as a body parame ...