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

What is the best way to ensure that my mat-slide-toggle only changes when a specific condition is met?

I'm having an issue with a function that toggles a mat-slide-toggle. I need to modify this function to only toggle when the result is false. Currently, it toggles every time, regardless of the result being true or false. I want it to not toggle when t ...

I'm currently endeavoring to integrate SignalR into my Vue project and encountering an issue

Currently, I am working on a project using Vue with TypeScript and I am interested in integrating SignalR. I have thoroughly studied the documentation provided by '@dreamonkey/vue-signalr' on how to utilize SignalR. import { VueSignalR } from &ap ...

Exploring the method of retrieving nested JSON objects in Angular

When my API sends back a JSON response, my Angular application is able to capture it using an Interface. The structure of the JSON response appears as follows: { "release_date":"2012-03-14", "genre_relation": ...

Creating a function in TypeScript that returns a string containing a newline character

My goal is to create a function that outputs the text "Hello" followed by "World". However, my current implementation does not seem to be working as expected. export function HelloWorld():string{ return "Hello"+ "\n"+ "W ...

Is there a solution for the error "Unable to persist the session" in a Next.js application that utilizes Supabase, Zustand, and Clerk.dev for authentication?

I have successfully set up a Next.js application with Clerk.dev for authentication and Supabase for data storage. I'm also leveraging Zustand for state management. However, an error is plaguing me, stating that there's "No storage option exists t ...

There has been an unhandled runtime error: [object ProgressEvent] occurring with Next.js/Typescript

Exploring the world of nextJS and typescript is new to me. I am currently working on creating a simple blog using nextJS/typescript with a sanity CMS backend. Everything seems to be running smoothly during development, but then I encounter this Unhandled R ...

Shifting Angular Component Declarations to a New Location

Here's a question that might sound silly: In my Angular project, I am looking to reorganize my component declarations by moving them from angular.module.ts to modules/modules.modules.ts. The goal is to structure my src/app directory as follows: src ...

Angular functions are executed twice upon being invoked within the html file

I decided to kick-start an Angular project, and I began by creating a simple component. However, I encountered a perplexing issue. Every time I call a function in the HTML file from the TypeScript file, it runs twice. TS: import { Component, OnInit } from ...

What is the process for searching my database and retrieving all user records?

I've been working on testing an API that is supposed to return all user documents from my Mongo DB. However, I keep running into the issue of receiving an empty result every time I test it. I've been struggling to pinpoint where exactly in my cod ...

Can Angular 4 experience race conditions?

Here is a snippet of my Angular 4 Service code: @Injectable() export class MyService { private myArray: string[] = []; constructor() { } private calculate(result): void { myArray.length = 0; // Perform calculations and add results to myAr ...

Encountering difficulties when attempting to load a module with the "js" extension in a TypeScript environment

When making a GET request with Systemjs, the extension .js is not being added to the URL. These are my TypeScript Classes customer.ts import {Address} from "./Address"; export class Customer { private _customerName: string = ""; public Customer ...

Tips for incorporating nested generics in Typescript

Currently, I am developing a straightforward activity execution framework that allows developers to define activities which can be executed within a workflow. To enhance type safety and boost developer productivity by utilizing type hints, I aim to incorp ...

What are the steps to expand the express object with TypeScript?

I am facing an issue where, after compiling a typescript project, the express import import {Request, Response} is not showing up. I am now attempting to use require, but I am unsure of how to extend the express object and utilize req and res. Any assistan ...

Eliminate the chosen and marked items from a list - Angular 2+/ Ionic 2

Currently, I have a checkbox list on my page. Whenever a user selects the "Save" button, the checked items should be removed from the list and moved to the saved tab that is also displayed. While I have successfully implemented the functionality for removi ...

Instructions for utilizing ObjectId with a string _id on the client side

Is there a way to retrieve a document using the _id in string format? Here is an example of the code on the client side: 'use client' ... const Page(){ ... fetch("api/get_data", { method: 'POST', ...

Binding data to custom components in Angular allows for a more flexible

In my current scenario, I am looking to pass a portion of a complex object to an Angular component. <app-component [set]="data.set"></app-component> I want the 'data.set' object in the parent class to always mirror the 'set&apo ...

The absence of essential DOM types in a TypeScript project is causing issues

Recently, I've been working on setting up a web app in TypeScript but I seem to be missing some essential types that are required. Every time I compile using npm run build, it keeps throwing errors like: Error TS2304: Cannot find name 'HTMLEleme ...

Obtaining the dimensions of each individual child component within an NgTemplate

I have the following code snippet within my template. While I can iterate through its components using `get`, it does not return an object that allows me to access deeper into the HTML attributes. <ng-template #container></ng-template> Compon ...

Positioning a Box tag at the bottom using MUI 5

My goal is to position a Box tag at the bottom of the page. Current Behavior: https://i.stack.imgur.com/ZupNo.png I am looking to place a TextField and send button at the bottom of the page on both browser and mobile. I want user messages to be above th ...

What is the process for extracting the elements of an array fetched from a service in Angular 2?

Currently, I am learning Angular 2 + PrimeNG and going through a quick start project available at the following link: https://github.com/primefaces/primeng-quickstart The project is a CRUD application and it functions flawlessly. The data is neatly displa ...