An example in Typescript for setting an initial/default value for a data type

Can you create a Type with a default value included?

For example:

type Animal = {
    kind : "animal"
    Legs : number,
    CanFly: boolean
}

const monkey: Animal = { Legs: 4, CanFly: false};  //In this line, clients must initialize the same value `kind : "animal"`

I want to include an attribute named kind and use it to deduce the object and make decisions. However, in the subsequent line, I expect clients to provide the same value for all initializations. Otherwise, TypeScript compiler will generate an error 'Property 'kind' is missing in type'.

Is there a way to set a default value without requiring clients to pass it back?

Answer №1

When working with TypeScript, it's important to remember that it is a structurally-typed language. This means that when you create a `type` or `interface`, you are defining a specific shape that other objects must adhere to. It's worth noting that assigning defaults within TypeScript types is not supported.

type Animal = {
  kind : "animal"
  Legs : number,
  CanFly: boolean
}

If your type definition includes properties like `kind: "animal"` as a string literal type, this indicates that only that exact value can be assigned to it. In this case, any object created using the `Animal` shape must have `kind: "animal"` specified.

To implement discriminated unions in TypeScript, you could consider creating more specific types instead of a generic one such as 'Animal'. For instance:

type Snake = {
  kind: "snake"
  Legs : number,
  CanFly: boolean
}

type Dolphin = {
  kind: "dolphin",
  Legs: number,
  CanFly: boolean
}

type Monkey = {
  kind: "monkey",
  Legs: number,
  CanFly: boolean
}

These specific types can then be used to create a discriminated union like so:

type Animal = Snake | Dolphin | Monkey 

To summarize, TypeScript focuses on defining shapes rather than providing default values within type declarations. If an object does not align with a specific shape defined by a TypeScript type, it cannot be considered as that type.

Answer №2

To simplify the code, you can implement a factory method:

type Creature = {
    type : "creature"
    Legs : number,
    CanFly: boolean
}

function createCreature(properties: Omit<Creature, 'type'>): Creature {
    return {
        type: 'creature',
        ...properties,
    };
}

const dragon = createCreature({ Legs: 6, CanFly: true});

Answer №3

To implement a class instead of an object literal, you can use the following approach:

export interface Animal {
    type: string;
     Legs : number;
     CanFly: boolean;
   }
   
   export class AnimalInfo implements Animal {
       type: string;
       Legs : number;
       CanFly: boolean;

       static create () {
          return new AnimalInfo({});
       }
   
       public constructor (animal: Partial<Animal>) {
          this.type = animal.type || "default type";
          this.Legs= animal.Legs || -1;
          this.CanFly = animal.CanFly || false;
       }
   }

const dog = AnimalInfo.create();

const cat = new AnimalInfo({type: "domestic", Legs: 4, CanFly: false});

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

Stop WebStorm from automatically importing code from a different Angular project within the same workspace

I currently have an angular repository that consists of two projects: a library and an Angular application. To link the library to my project, I utilized the npm link command. Within the package.json file, I specified the entry as follows: ... "my-lib ...

Error TS2322: The function expecting a type of 'FormEventHandler<HTMLFormElement>' cannot be assigned the type '(data: TicketFullDTO) => Promise<void>'

I am currently working on creating an edit form to modify data from a database based on its ID. Here is my approach: import React, {FormEvent, useEffect, useState} from "react"; import TextField from "@material-ui/core/TextField" ...

Using the concat operator along with the if statement in Angular to make sequential requests based on certain conditions

Managing multiple HTTP requests in a specific order is crucial for my event. To achieve this, I am utilizing the concat operator from rxjs. For instance, upon receiving data from the first request, I update local variables accordingly and proceed to the ne ...

Unfortunately, the utilization of an import statement outside a module is restricted when working with Electron

Is there a solution to the well-known problem of encountering the error message "Cannot use import statement outside a module" when working with an Electron-React-Typescript application? //const { app, BrowserWindow } = require('electron'); impor ...

I implemented progress bars in Angular 2 that have changing maximum values. The service updates the maximum value for each bar dynamically. Currently, the progress bars are functioning at 100% capacity

this.games=[ {"val":50, "name":"Articlescontributed","max":35}, {"val":30 ,"name":"Articlesrated", "max":999}, {"val":20, "name":"Views", "max":35}, {"val":30, "name":"Ratings", "max":35}, {"val":20, "name":"Follower", "max":200}, { ...

Sending data between components in Angular can be achieved by using various methods. One common approach is to utilize

I am encountering an issue with a component named customers.component Below is the code from the customers.component.ts file: @Component({ selector: 'app-customer', templateUrl: './customer.component.html', styleUrls: ['./cu ...

Adding properties to React Component

Due to security reasons, I am required to update the ant design library in my codebase from version 3 to 4. In the past, this was how I used the icon: import { Icon } from 'antd'; const Demo = () => ( <div> <Icon type="smile" ...

Absence of property persists despite the use of null coalescing and optional chaining

Having some trouble with a piece of code that utilizes optional chaining and null coalescing. Despite this, I am confused as to why it is still flagging an error about the property not existing. See image below for more details: The error message display ...

Generate an object in Typescript that includes a dynamic property calculated from an input parameter

Is there a way to achieve the following function in TypeScript? function f<T extends 'a' | 'b'>(t : T): {[t]: ...} { return {[t]: ...} } This code is intended to make f('a') have type {'a': ...} and similarl ...

Achieving Jest integration with Angular 9 in a Storybook setup

We are currently utilizing Storybook 5 alongside Angular 9, with Jest 26 for some of the testing procedures. The issue we're facing arises when using Typescript version below 3.8.0 - a requirement for Angular 9's ng build --prod. This results in ...

Creating TypeScript models from a JSON response in React components

My Angular 2 application retrieves a JSON string, and I am looking to map its values to a model. According to my understanding, a TypeScript model file is used to assist in mapping an HTTP Get response to an object - in this case, a class named 'Custo ...

When additional lines are drawn elsewhere on the HTML5 Canvas, the diagonal lines will gradually appear thicker and more pronounced

For horizontal and vertical lines, using a translation of 0.5 for odd stroke widths results in crisper and sharper lines. But what about diagonal lines? Link to jsfiddle <!DOCTYPE html> <html lang="en"> <body style="background: black"& ...

Challenges encountered when passing objects with Angular 2 promises

I am encountering a problem when using a promise to retrieve a Degree object in Angular 2. The initial return statement (not commented out) in degree.service functions correctly when paired with the uncommented implementation of getDegree() in build.compon ...

There seems to be a problem fetching the WordPress menus in TypeScript with React and Next

Recently I've started working on a project using React with TypeScript, but seems like I'm making some mistake. When trying to type the code, I encounter the error message: "TypeError: Cannot read property 'map' of undefined". import Re ...

When using a function as a prop in a React component with Typescript generics, the type of the argument becomes unknown

React version 15 or 18. Typescript version 4.9.5. When only providing the argument for getData without using it, a generic check error occurs; The first MyComponent is correct as the argument of getData is empty; The second MyComponent is incorrect as t ...

Tips on continuously making calls to a backend API until receiving a successful response with status code 200

While working on my Angular project, I have encountered a situation where I need to make calls to a backend API. If the response is not 200 OK, I have to keep calling the API every 30 seconds until I receive a successful response. In Angular, I usually ca ...

Trouble configuring a React TypeScript router has arisen

Recently, I have successfully set up multiple routers in TypeScript. However, I am facing challenges in implementing the same in a new project for some unknown reason. import React from 'react'; import Container from './Components/Containers ...

Tips for adding a "Select All" feature to a dropdown list?

Currently, I have a dropdown list with a filter for IN and OUT values. The functionality is working as expected: <select class="form-select" style="max-width: 100px" [ngModel]="selectedBrand" (ngModelChange)="onChangeT ...

Rect cannot be resized using mouse events

I am currently working on resizing the rectangle inside the SVG using mouse events. To achieve this, I have created another circle shape at the right bottom edge of the rectangle and implemented resize events on that shape. However, I'm facing an issu ...

Unraveling TypeScript code expressions

I am seeking clarification on the meaning and practical application of this particular expression. ((identifier:string) => myFunction(identifier))('Hi') myFunction const myFunction = (str:string) => { console.log(str) } The output displ ...