Is there a method to accurately pinpoint the specific type?

Is there a way to optimize the validateField function to narrow down the type more effectively?

type TStringValidator = (v: string) => void;
type TNumberValidator = (v: number) => void;

type TFields = 'inn' | 'amount';

interface IValidators {
  inn: TStringValidator[];
  amount: TNumberValidator[];
}

const handleString: TStringValidator = (value: string) => {};
const handleNumber: TNumberValidator = (value: number) => {};

const validators = {
  inn: [handleString],
  amount: [handleNumber],
} satisfies IValidators;

function validateField(field: TFields, value: string | number) {
  const fieldValidators = validators[field];

  for (const validator of fieldValidators) {
    // The issue lies here
    const result = validator(value);
  }

  return;
}

Link to the TS playground.

Expect validator(value) call not to throw TS error:

Argument of type 'string | number' is not assignable to parameter of type 'never'.
  Type 'string' is not assignable to type 'never'.(2345)
(parameter) value: string | number

The TypeScript compiler seems to struggle with inferring the type for the dynamic validator based on the field value. Perhaps some refactoring of the validateField function could help.

Answer №1

To prevent the never type, you can establish a list of all approved types in the validator

type AllowedTypes = string & number;

then when calling the generic validator function, simply convert the variable to the allowed type

const result = validator(value as AllowedTypes);

here is a complete example

type TStringValidator = (v: string) => void;
type TNumberValidator = (v: number) => void;

type TFields = 'inn' | 'amount';
type AllowedTypes = string & number;

interface IValidators {
  inn: TStringValidator[];
  amount: TNumberValidator[];
}

const handleString: TStringValidator = (value: string) => {};
const handleNumber: TNumberValidator = (value: number) => {};

const validators = {
  inn: [handleString],
  amount: [handleNumber],
}
satisfies IValidators;

function validateField(field: TFields, value: string | number) {
  const fieldValidators: (TNumberValidator | TStringValidator)[] = validators[field];

  for (const validator of fieldValidators) {
    const result = validator(value as AllowedTypes);
  }

  return;

Answer №2

It seems that the issue lies in the uncertain type of your value, whether it is a string or number, and TypeScript is unable to determine the specific type validator being used within the loop (either TStringValidator or TNumberValidator). While the structure may be a tad awkward, you can still address the problem with the following approach:

function validateField(field: TFields, value: string | number) {
  const fieldValidators = validators[field];

  Object.keys(validators).forEach(key => {
    if (key === 'inn' && typeof value === 'string') {
      const result = validators[key][0](value)
    }
  })

  return;
}

There's always room for improvement in the code snippet provided above, but the concept should be clear.

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

Struggling to update TypeScript and encountering the error message "Unable to establish the authenticity of host 'github.com (192.30.253.113)'"

While attempting to update my version of TypeScript using npm, I ran into an issue when trying to execute the following command: localhost:Pastebin davea$ npm install typescript/2.8.4 --save-dev The authenticity of host 'github.com (192.30.253.113)&a ...

Adjusting the timeout for a particular operation according to its unique identifier

I am looking for a solution to call a method that posts an answer after an input change in my Angular project. I want to reset the timeout if another input change occurs to avoid multiple posts. Is there a smart way to achieve this? My project involves po ...

To run multiple environments with react-native-dotenv in a React Native project using Typescript, only the local environment is activated

Currently, I am facing an issue while trying to initialize my React Native app with TypeScript in three different environments - development, local, and testing. When I attempt to run APP_ENV=testing expo start or APP_ENV=development expo start, it always ...

Tips for managing errors when using .listen() in Express with Typescript

Currently in the process of transitioning my project to use Typescript. Previously, my code for launching Express in Node looked like this: server.listen(port, (error) => { if (error) throw error; console.info(`Ready on port ${port}`); }); However ...

Error encountered when attempting to utilize Path Aliases in Angular 11.tsconfig

Currently, I am working on a project using Angular 11 and aiming to utilize short imports like import {smthg} from '@common' instead of import {smthg} from '../../../common' However, I keep encountering errors in IDEA: TS2307: Cannot f ...

Nested function TypeScript declarations

Currently, I am attempting to define a type for my controller function in (nodejs) similar to the following export const registerUser = asyncWrap(async function(req:Request, res:Response, next:NextFunction) { res.status(200).json({ success: true}); }) ...

Sharing a Promise between Two Service Calls within Angular

Currently, I am making a service call to the backend to save an object and expecting a number to be returned via a promise. Here is how the call looks: saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> { item.modifiedDa ...

Having an excess of 32 individual byte values

My current project involves developing a permission system using bitwise operators. A question came up regarding the limitation of having only 32 permissions in place: enum permissions { none = 0, Founder = 1 << 0, SeeAdmins = 1 << ...

Custom "set attribute" feature in TypeScript

One issue I faced was resolved by creating the function shown below : function setProperty<T extends Record<string, string>>(obj: T, key: keyof T) { obj[key] = "hello"; } However, when I tried to compile the code, I encountered an ...

Initial position of the range slider in IONIC 2

I have been searching the web extensively to find a solution to this particular issue. I am working with a range slider and trying to set its default starting values, but so far, I haven't had any luck. I've checked both the official documentatio ...

Troubleshooting an Issue with MediaStreamRecorder in TypeScript: Dealing with

I've been working on an audio recorder that utilizes the user's PC microphone, and everything seems to be functioning correctly. However, I've encountered an error when attempting to record the audio: audioHandler.ts:45 Uncaught TypeError ...

Sorting elements in an array based on an 'in' condition in TypeScript

I am currently working with an arrayList that contains employee information such as employeename, grade, and designation. In my view, I have a multiselect component that returns an array of grades like [1,2,3] once we select grade1, grade2, grade3 from the ...

The installation of @types/jquery leads to an unnecessary global declaration of $

In my package.json file, I have the following dependencies defined: { "dependencies": { "@types/jquery": "^3.5.5", } } This adds type declarations through @types/jquery/misc.d.ts, including: declare const jQuery: JQue ...

Derive the property type based on the type of another property in TypeScript

interface customFeatureType<Properties=any, State=any> { defaultState: State; properties: Properties; analyzeState: (properties: Properties, state: State) => any; } const customFeatureComponent: customFeatureType = { defaultState: { lastN ...

Can a string array be transformed into a union type of string literals?

Can we transform this code snippet into something like the following? const array = ['a', 'b', 'c']; // this will change dynamically, may sometimes be ['a', 'e', 'f'] const readonlyArray = arr ...

Could this type declaration in the Vue decorator constructor be accurate?

When using Vue decorator notation, I typically write it like this: @Prop({ type: Object || null, default: null }) However, I noticed in the Vue documentation that they use array notation: @Prop({ type: [ Object, null ], default: null }) Is there a specif ...

Some files are missing when performing an npm install for a local package

My project is structured like this: ├── functions/ │ ├── src │ ├── lib │ ├── package.json ├── shared/ │ ├── src │ | ├── index.ts | | ├── interfaces.ts | | └── validator_cl ...

Is today within the current week? Utilizing Moment JS for time tracking

There is a problem that I am facing. Can you assist me in determining whether the day falls within the current week? I am currently developing a weather forecast service and need to validate if a given day is within the current week. The only clue I have ...

Found a minor syntax problem in an Angular service related to error handling declaration

As I was working on customizing the Angular tutorial to fit my needs, I found myself wanting to merge the two error handler methods showcased in the tutorial into one. I appreciate the functionality of both methods and believe combining them will be benefi ...

Validate that the input is an array

Looking for a way to determine if a function parameter is an array or not, and then process it accordingly. If the parameter is not an array, convert it into an array before performing the desired function. For example: interface employee { first: st ...