Need a certain string as an optional key within a TypeScript interface

Is there a way to define a type and set it as the optional key's type in an interface for t-shirt size props added to an object?

type Size = `xxs` | `xs` | `s` | `m` | `l` | `xl` | `xxl`;

interface Sizes {
  [key: Size]: string;
   ^^^
}

Encountering the error:

An index signature parameter type cannot be a union type. Consider using a mapped object type instead.ts(1337)

Upon researching, I came across this question, and adjusted my code as below:

type Size = `xxs` | `xs` | `s` | `m` | `l` | `xl` | `xxl`;

interface Sizes {
  [key in Size]: string;
   ^^^^^^^^^^^
}

However, faced with subsequent errors:

A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.ts(1169)

A computed property name must be of type 'string', 'number', 'symbol', or 'any'.ts(2464)

Cannot find name 'key'.ts(2304)

Seeking clarity on my implementation, any insights would be greatly appreciated.

Answer №1

When it comes to mapped types in TypeScript, they are distinct from interfaces. Instead of defining a mapped type as an interface, you can opt for a type alias like this:

type TSizes = { [K in Size]?: string };

It's worth noting that by including the ?, you're allowing the properties to be optional, which is often desirable.

Once you have defined such a named type, you can further extend it with an interface (since all property names are known at compile time):

interface ISizes extends TSizes { }

Alternatively, you could utilize TypeScript's built-in utility types like Partial and Record to combine both functionalities into a single interface:

interface Sizes extends Partial<Record<Size, string>> { }

With this setup, Sizes becomes an interface where keys from Size are optional with values of type string:

const s: Sizes = {
    s: "foo",
    m: "bar",
    xxl: "bazzz"
}

Hopefully, this information proves helpful. Best of luck with your TypeScript endeavors!

Feel free to experiment with the code on the TypeScript playground.

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 reason that the command `npx create-react-app my-app --typescript` is not providing me with the expected TypeScript files?

I used the command npx create-react-app my-app --typescript to create my React project, but it seems like I still ended up with the default JavaScript boilerplate files. I was expecting to see files with a .tsx or .ts extension and use import * from as R ...

Guide to making API calls within the matcher function of Angular 7 routes

Currently, I am working on an Angular 7 project that involves a route matcher function. My goal is to make an API call to retrieve an array and then check if that array contains a specific URL slug. My Attempts So Far: I attempted to call the API using AP ...

Bidirectional data binding in Angular 9 form controls

Implementing two-way binding in an Angular 9 form I attempted to use [(ngmodel)] in the form, however it resulted in an error. This feature has been deprecated in Angular 6 and newer versions. ...

What could be causing my function to not provide the expected output?

Whenever I try to invoke the function from another part of the code, I encounter an issue where it returns undefined before actually executing the function. The function is stored in a service. login.page.ts: ngOnInit(){ console.log(this.auth.getRole()) ...

Display a field using React and JavaScript depending on the output of an asynchronous function

I'm working on an asynchronous function to query and return a value. Here's an example of what I have in mind: async function verifyProfileFeature(values: any) { const data = await client.query<any>({ query: PROFILE_QUERY, ...

Please ensure that the property name is a valid type, such as 'string', 'number', 'symbol', or 'any'

Can anyone help me convert this JavaScript file to Typescript? import React, { useState } from 'react'; import { Button } from './Button'; import { Link } from 'react-router-dom'; import './Navbar.css'; import Settin ...

The formControl value is not being shown on the display

I am facing an issue with a form that has multiple fields created using formGroup and formControlName. The challenge arises when I launch the application and need to retrieve data from the back end to display it on the view. The specific problem I'm ...

Unlocking Angular 10: Harnessing the Power of JWT for Seamless

I am encountering an issue with JWT login in angular. Although I have successfully logged in and saved the token, my frontend isn't reflecting the changes Auth.service.ts import { Injectable } from '@angular/core'; import { HttpClient, Http ...

What are the real-world applications of "Type-only Field Declarations"?

Source: Type-only Field Declarations. interface Animal { dateOfBirth: any; } interface Dog extends Animal { breed: any; } class AnimalHouse { resident: Animal; constructor(animal: Animal) { this.resident = animal; } } class DogHouse ext ...

Creating a blueprint for an object that inherits from another interface

I am looking to create an interface that includes unknown properties for one object, while also extending it with known properties from another interface. Here is my attempt: public async dispatchMessage(): Promise<{} extends IHasResponseFormat> I ...

Module error caused by Typescript path inconsistency

After creating a new model named "project" within the existing project, I encountered an error when attempting to import the class into another typescript file in VS2019. The specific error message thrown is as follows: "ts2307 cannot find module ' ...

I am experiencing issues with my HTML select list not functioning properly when utilizing a POST service

When using Angularjs to automatically populate a list with *ngFor and then implementing a POST service, the list stops functioning properly and only displays the default option. <select id="descripSel" (change)="selectDescrip()" > <option >S ...

Can you explain the TypeScript type for the queryKey in React Query?

Currently utilizing react query in conjunction with typescript. What should be the type of arguments passed to the function? export const useIsTokenValid = () => { const { data: token } = useQuery<string | null>(['token'], getToken, { r ...

Running into issues with TypeScript in conjunction with Redux-Form and React-Redux connect

My excitement for TypeScript grew until I encountered some frustrating incompatibilities between Redux-Form and React-Redux. I am aiming to wrap a component decorated with reduxForm using the connect decorator from react-redux—this method has always bee ...

Issue with Socket.io Client: Consistently receiving error messages for an incorrect

Here is the server-side code: import http from 'http'; import Koa from 'koa'; import { Server } from 'socket.io'; (async () => { const app = new Koa(); var server = http.createServer(app.callback()); var io = new Se ...

Updating events instantly with a single click in Angular 6: A step-by-step guide

Hello there, I am currently diving into learning Angular 6 and I have encountered a query. I want to achieve a functionality where upon clicking a button, the text on the button changes as well as the corresponding event that triggers when the button is cl ...

The Power of TypeScript's Union Types

Provided: Reducer only accepts one of the following actions: interface ItemAction { type: 'ADD_TODO'|'DELETE_TODO'|'TOGGLE_TODO', id: number } interface QueryAction { type: 'SET_QUERY', query: string ...

Calling gtag("event") from an API route in NextJS

Is there a way to log an event on Google Analytics when an API route is accessed? Currently, my gtag implementation looks like this: export const logEvent = ({ action, category, label, value }: LogEventProps) => { (window as any).gtag("event&quo ...

Creating an object array in JavaScript with an invalid index initialization

As an illustration, I start by creating a constructor and initializing an array of objects in JavaScript. function SomeConstruct(val1, val2) { this.val1= val1; this.val2= val2; } var someCons= new Array(); someCons[0] = new SomeConstruct(12, 40) ...

Struggling to make fetch function properly within a NextJs middleware function

I am having trouble with redirecting a user to /login if the authentication token from Laravel is invalid. I am attempting to retrieve the user and, if resp.ok() returns false, delete the invalid "token" cookie and direct the user to /login. However, I con ...