Change the property value prior to running TypeScript validation

I possess the following object:

const translations = {
    msg_hello: 'Hello',
    msg_bye: 'Bye'
}

In addition, I have a function that is structured as such:

const generateTranslation = (partialKey: string): keyof typeof translations {
    return `msg_${partialKey}`;
}

Is there a method to validate if the generated translation key will be acceptable? For instance:

generateTranslation('hello'); // valid
generateTranslation('no'); // invalid

Answer №1

To start, it is essential to extract permissible values from the translations object. To achieve this, the translations object needs to be made immutable.

const translations = {
    msg_hello: 'Hello',
    msg_bye: 'Bye'
} as const;

For better readability, a helper type can be created:

type Translations = typeof translations;

Utilizing template literals, it becomes possible to deduce the string following the underscore character _:

type GetSuffix<T> = keyof T extends `msg_${infer Suffix}` ? Suffix : never;

type Test = GetSuffix<Translations> // "hello" | "bye"


Subsequently, the restriction can be applied:


const generateTranslation = <
    Key extends GetSuffix<Translations>
>(partialKey: Key): `msg_${Key}` => `msg_${partialKey}`

It should be noted that partialKey has been inferred using GetSuffix<Translations> to enable the application of an explicit return type, msg_${Key}.

Complete example:

const translations = {
    msg_hello: 'Hello',
    msg_bye: 'Bye'
} as const;

type Translations = typeof translations;

type GetSuffix<T> = keyof T extends `msg_${infer Suffix}` ? Suffix : never

type Test = GetSuffix<Translations> // "hello" | "bye"

const generateTranslation = <
    Key extends GetSuffix<Translations>
>(partialKey: Key): `msg_${Key}` => `msg_${partialKey}`

const result = generateTranslation('hello'); // good --->  "msg_hello"
generateTranslation('no'); // bad

Playground

Answer №2

Automatically retrieving dynamic strings like this may not be possible with keyof, but you can manually define a type that includes all valid values and use it to validate the arguments:

const translations = {
    msg_greetings: 'Greetings',
    msg_goodbye: 'Goodbye'
};

type validKeys = 'greetings' | 'goodbye';

const generateMessage = function (key: validKeys): keyof typeof translations {
    return `msg_${key}`;
}

generateMessage('greetings'); // works fine
generateMessage('farewell'); // will not work

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

React Formik - application triggers an undesired submission request when the Enter key is pressed in the input field

Whenever I enter a value in the "name" field and hit Enter, the app sends a request and the address bar in the web browser changes to http://localhost:3000/?name=something. However, if I simply add another input field to the form, the app's behavior c ...

Ways to supersede an external TypeScript interface

For my TypeScript project, I am utilizing passport. The provided DefinitelyTyped type definition for passport modifies the Express request to include a user property. However, it defines the user as an empty interface: index.d.ts declare global { nam ...

Exploring the method for obtaining parameters from a generic constructor

I have a customized class called Collection, which takes another class as a parameter named personClass. I expect the method add to accept parameters that are used in the constructor of the class User class Person { constructor(public data: object) { } ...

The TypeScript find() method on an array are showing an error message that says, "There is no overload that matches this call

Issue Description I encountered a problem while using TypeScript's find() method for an array. Whenever I input a value, it does not work properly and displays an error message stating, "No overload matches this call". Code Snippet addOption(event: ...

What is the process for enabling Namespaces in CRA?

When creating a TypeScript React app, I used the following command: yarn create react-app my-app --template typescript This setup compiles my project using Babel and bundles it with webpack. Now, I want to utilize TypeScript namespaces, which are not nat ...

The directive for accepting only numbers is not functioning in versions of Chrome 49.xx.xx and earlier

I have implemented a directive in Angular 6 to allow only numbers as input for certain fields. The directive code is shown below: import { Directive, ElementRef, HostListener } from '@angular/core'; @Directive({ selector: '[NumbersOnly]& ...

What is the best way to showcase several images using Sweet Alert 2?

In the process of developing my Angular 2 application, I have incorporated sweet alert 2 into certain sections. I am looking to showcase multiple images (a minimum of two) at the same time in the pop-up. Does anyone have any suggestions on how to achieve ...

Rotate object within HTML table

I have a simple data structure as shown below: [ { "ClientId": 512, "ProductId": 7779, "Date": "2019-01-01", "Quantity": 20.5, "Value": 10.5 }, { "ClientId": 512, "ProductId": ...

What are the steps to correct a missing property in an established type?

Currently, I am in the process of converting an existing Node.js + express application from plain JS to TypeScript. Although I understand why I am encountering this error, I am unsure about the correct approach to resolve it. The type "Request" is coming f ...

Angular 13: SyntaxError Encountered: Token 'export' Not Recognized

After upgrading Angular from version 12 to 13, I encountered an error when running the app: "Uncaught SyntaxError: Unexpected token 'export'." Here are some additional details for context: In the angular.json configuration file, I had specified ...

Error in AngularX TS: Trying to invoke a type that does not have a callable signature

Encountering an issue while working on a component, specifically during ng serve/build process. Please note that this error is different from any console errors, despite what some may think. The expected outcome is for the code to successfully build and ru ...

Sending a XML file from a Vue application to an ASP.NET Core backend using axios

I'm encountering difficulties when trying to upload an xml file using axios to my asp .net server. Below is the code snippet I am using on the vue side to retrieve and upload the xml file: uploadXmlFile(file: any) { const rawFile = new XMLHttpRequ ...

Ensure to pass the correct type to the useState function

I have a basic app structured like this import React, { useState } from 'react' import AddToList from './components/AddToList' import List from './components/List' export interface IProps{ name: string age: number url: ...

Tips for personalizing the Material UI autocomplete drop-down menu

I'm currently working with Material UI v5 beta1 and I've been attempting to customize the Autocomplete component. My goal is to change the Typography color on the options from black to white when an item is selected. However, I'm struggling ...

Tips for utilizing the JS attribute "offsetWidth" within Angular 4

I am attempting to retrieve the width of an element using JavaScript in my Angular application. document.getElementsByClassName("element")[0].offsetWidth; However, I keep encountering the following compilation error: Property 'offsetWidth' d ...

Breaking up React code within the React.createElement() function

I am encountering an issue with lazily loaded pages or components that need to be rendered after the main page loads. When using createElement(), I receive the following error: LazyExoticComponent | LazyExoticComponent is not assignable to parameter of ty ...

Utilizing the Redux Connect HOC's wrapped component type in React.RefObject without the need for re-importing

My current setup involves a simple component that is wrapped with react-redux and has a ref with forwardRef: true, demonstrated below: // Button.tsx class Button extends React.Component { // ... } // ... export default connect(mapStateToProps, null, n ...

Leveraging process.env with TypeScript

Is there a way to access node environment variables in TypeScript? Whenever I try using process.env.NODE_ENV, I encounter the following error : Property 'NODE_ENV' does not exist on type 'ProcessEnv' I even tried installing @types/no ...

List the hours using TypeScript

My data table is displaying records including a column for hours spent and a row showing the total sum of those hours. While the hours are being added correctly, the minutes display as NaN, such as 52:Nan. Can someone assist me in resolving this issue? co ...

Leveraging Multiple @Input Decorators in Ionic 3 and Angular 2

Within my Ionic 3 project, I have developed a custom component called my-component. Utilizing the angular @Input functionality, data can be passed to this component with ease. In this case, I have two inputs defined as: @Input('finder') myFinder ...