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?: StyleProp<TextStyle>;
  column?: ColumnValues.one | ColumnValues.two | ColumnValues.three;
}

const DynPut: FC<Props> = Props => {
...
return(
...
)

I have integrated this DynPut into another component and input the value of 10 to the Column Prop, however Typescript is not generating any errors. How can I configure Typescript to throw an error when a value greater than 3 is supplied to the Column Prop?

  <DynPut
    title="Add Items"
    style={{backgroundColor: 'yellow'}}
    titleStyle={{backgroundColor: 'green'}}
    titleContainerStyle={{backgroundColor: 'green'}}
    textInputStyle={{borderWidth: 5}}
    column={10}
  />

Answer №1

This issue bears resemblance to a similar problem discussed here. However, the previous solution needs slight adjustments to address this specific problem. If you believe it's a duplicate, please flag it for review.

The primary issue at hand is that the `number` type in TypeScript can be assigned to a numeric enum even if it doesn't align with the enum values or requirements. For more context, refer to this answer.

To validate the provided number, we have to convert all enum numbers and the given `column` number into strings. Only then can we safely validate them.

Here's an example to consider:

enum ColumnValues {
    one = 1,
    two = 2,
    three = 3,
}

// Convert each enum numeric value into a string.
// Example: 3 -> "3"
type Enumerate<Enum> = Enum extends number | string ? keyof {
    [Prop in `${Enum}`]: Prop
} : never

// Get the stringified enum values
type Result = Enumerate<ColumnValues> // "0" | "1"

// Get a union of object values
type Values<T> = T[keyof T]

// Check if the provided initial value matches a stringified enum value
// If yes, allow the value and return the initial value
// If not, return 'never' to trigger a TypeScript error
type IsKeyValid<InitialValue extends number, Enum> =
    `${InitialValue}` extends Enumerate<Enum> ? InitialValue : never

type Props<Count extends number> = {
    column: IsKeyValid<Count, ColumnValues>;
}
const DynPut = <Count extends number>(props: Props<Count>) => { }

DynPut({ column: 1 }) // ok
DynPut({ column: 5 }) // error

my article as well.

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

An error should not be thrown if the object is potentially 'undefined', as there is a filter in place from rxjs

During my service refactoring process, I encountered a frustrating issue. The API I am working with returns an object with various optional properties. To work with these properties, I need to check if they are undefined or not using an if statement, other ...

Encapsulate the module function and modify its output

I am currently utilizing the node-i18n-iso-countries package and I need to customize the getNames function in order to accommodate a new country name that I wish to include. At the moment, I am achieving this by using an if-else statement like so: let cou ...

Transform current JSON data into formatted JSON format using JavaScript or TypeScript

I have a JSON structure that needs to be reformatted in order to meet the requirements of an external service. Although the current format is complex and cannot be altered, I need to modify it to match the desired output for the external service. Current ...

Is there a way to extract a specific item from a ListView by tapping on it in Nativescript?

Attempting to retrieve data from a tap event using angular2 + typescript: This is the html code for the component: <RadListView row="1" [items]="groceryList" [class.visible]="listLoaded" (tap)="seeItem($event)" swipeActions="true" (itemSwipeProgr ...

Avoid using `@typescript-eslint/no-floating-promises` when using a `const` function

Can anyone help me understand why the @typescript-eslint/no-floating-promises rule works with some async functions but not all? To my understanding, these two functions should be equivalent: const getUser = async (userId: string): Promise<User> => ...

Despite declaring a default export, the code does not include one

Software decays over time. After making a small modification to a GitHub project that was three years old, the rebuild failed due to automatic security patches. I managed to fix everything except for an issue with a default import. The specific error mess ...

The functionality of React setState seems to be malfunctioning when activated

Having encountered an unusual issue with react's setState() method. Currently, I am utilizing Azure DevOps extensions components and have a panel with an onClick event that is intended to change the state of IsUserAddedOrUpdated and trigger the addOr ...

Does an AsyncMethod().Result equivalent exist in typescript?

When working in C#, you have the ability to call the result of an asynchronous method synchronously by accessing the Result property. For example: var returnVal = AsyncMethod().Result; What is a similar approach in typescript? ...

Currently in the process of creating a carousel displaying images, I have encountered an issue stating: "An optional property access cannot be on the left-hand side of an assignment expression."

I am currently working on an Angular Image Carousel that utilizes a model to iterate through the images. However, I am encountering an error when attempting to access the first position. An error message stating "The left-hand side of an assignment expres ...

Expanding the range of colors in the palette leads to the error message: "Object is possibly 'undefined'. TS2532"

I am currently exploring the possibility of adding new custom colors to material-ui palette (I am aware that version 4.1 will include this feature, but it is a bit far off in the future). As I am relatively new to typescript, I am finding it challenging t ...

Converting HTML to PDF with rtl support using the JavaScript library jsPDF

I'm attempting to convert HTML to PDF using jsPDF in an Angular 5 project. Below is the code I have so far: import * as jsPDF from "jspdf"; . . . htmlToPdf(){ var doc=new jsPDF(); var specialElementHandlers = { '#content' : function ...

Is Angular CLI incorrectly flagging circular dependencies for nested Material Dialogs?

My Angular 8 project incorporates a service class that manages the creation of dialog components using Angular Material. These dialogs are based on different component types, and the service class is designed to handle their rendering. Below is a simplifie ...

HTML code for adding a dropdown menu inside a table cell

I am trying to set up a table where one cell functions as a dropdown menu. The data.field is being fetched from the backend and I want it to be displayed during rendering. Additionally, a fList is also retrieved from the backend. When a user clicks on th ...

Looking to retrieve the AssetLoadedFunc properties in the LoadAssets function? Wondering if you should use TypeScript or JavaScript

When I invoke this.AssetLoadedFunc within the function LoadAssets(callback, user_data) LoadAssets(callback, user_data) { this.glg.LoadWidgetFromURL("assets/Js/scrollbar_h.g", null, this.AssetLoaded, { name: "scrollb ...

Is it possible to incorporate React-Native components into a React.js project?

As a mobile developer diving into web development for the first time, I have a question: Can we utilize react-native libraries in reactjs? My main motivation for this inquiry is my quest for a segment-control tab similar to the one found on iOS, which yo ...

I'm perplexed as to why my array remains empty despite assigning a value to it in my controller. (Just to clarify, I am working with AngularJS, not Angular)

I spent a whole day debugging this issue without any luck. Issue: this.gridOptions.data = this.allTemplatesFromClassificationRepo ; **this.allTemplatesFromClassificationRepo ** remains an empty array. I have already called the activate() function to assig ...

When a function is transferred from a parent component to a child component's Input() property, losing context is a common issue

I have encountered an issue while passing a function from the parent component to the child component's Input() property. The problem arises when the parent's function is called within the child component, causing the this keyword to refer to th ...

Tips for maintaining type information when using generics in constructors

class Registry<Inst, Ctor extends new (...args: unknown[]) => Inst, T extends Readonly<Record<string, Ctor>>> { constructor(public records: T) { } getCtor<K extends keyof T>(key: K) { return this.records[key] } getIns ...

Angular 14: Deleting an item from a FormArray triggers unintended form submission due to Angular animation

After beginning to create animations for my app, I observed that deleting an element from a FormArray triggers a form submission. Custom form controls were developed using ControlValueAccessor, and certain FormGroups are passed through @Inputs. The animati ...

Retrieving the key from an object using an indexed signature in Typescript

I have a TypeScript module where I am importing a specific type and function: type Attributes = { [key: string]: number; }; function Fn<KeysOfAttributes extends string>(opts: { attributes: Attributes }): any { // ... } Unfortunately, I am unab ...