0

I am trying out an API using Typescript with local json file as storage (to test things out). I defined two interfaces, one for the DB model and one for the input from the request, with the model extending from the input interface, as the below.

export interface WorkoutInput {
    name: string;
    mode: string;
    equipment: string[];
    exercises: string[];
    trainerTips: string[];
}

export interface WorkoutModel extends WorkoutInput {
    id: string;
    createdAt: string;
    updatedAt: string;
}

However, when I had to update some fields in a WorkoutModel instance using the square brackets, I get an error since I haven't defined the index signature on either of the interfaces. I added the index signature, but this allows setting properties that aren't defined in the interface. For example:

export interface WorkoutModel extends WorkoutInput {
    [key: string]: string | string[];
    
    id: string;
    createdAt: string;
    updatedAt: string;
}

const workout: WorkoutModel = ...;
workout.hello = 'test';
workout['hello2'] = 'test2';

The last two lines don't throw any error, even though they are not part of the defined properties of the interface. As a workaround, I created a union type of the list of keys, and in the index signature, instead of making key's type as string, it would be this union type, however, this also produced an error saying to consider using a mapped object type instead, which after applying it changed the definition to the below.

type WorkoutModelKeys = 'id' | 'name' | 'mode' | 'equipment' | 'exercises' | 'trainerTips' | 'createdAt' | 'updatedAt';

export type WorkoutModel = WorkoutInput & {
    [key in WorkoutModelKeys]: string | string[];
} & {
    id: string;
    createdAt: string;
    updatedAt: string;
};

Indeed this gave an error when setting the keys hello and hello2 on the WorkoutModel instance and the code works fine with it, but I want to know if this is the only solution for this problem or is there another way this could have been solved without intersecting different types.

EDIT: Here is a reproducible scenario of the original issue.

hakuna matata
  • 3,243
  • 13
  • 56
  • 93
  • 1
    It doesn't sound like you *want* an index signature, since they explicitly are meant for situations without a predefined set of prop names. Seems like an XY problem. You say "However, when I had to update some fields in a WorkoutModel instance using the square brackets, I get an error since I haven't defined the index signature on either of the interfaces." Please show this happening in a [mre], since this is apparently your actual issue and you're trying to fix it, and index signatures aren't working out for you. – jcalz Jul 26 '22 at 16:47
  • @jcalz I added a link with a reproducible scenario of the original issue. – hakuna matata Jul 26 '22 at 17:08

0 Answers0