Search code examples
typescriptmapped-types

Is there a better way to construct types with properties from templated strings?


When I construct this type

type Test<Name extends string> = {
  [key in `a${Name}`]: 88;
  [key in `b${Name}`]: 21;
};

I get the error "A mapped type may not declare properties or methods.ts(7061)" However, the following works fine

type Test2<Name extends string> = {
  [key in `a${Name}`]: 88;
} & {
  [key in `b${Name}`]: 21;
};

Can someone explain the difference?

Also is there a better way to construct these types? It feels odd to use in for only one type.


Solution

  • Why you cannot declare additional properties is covered here: Typescript: Cannot declare additional properties on Mapped types

    A short answer: It seems like an unanticipated use case so not implemented.

    It's easy just to intersect a mapped and a usual type

    type Type = MappedType & UsualType;
    

    You could create a generic type to ease the case:

    type AddName<T, Name extends string> = {
        [K in keyof T as K extends string ? `${K}${Name}` : never]: T[K];
    }
    
    type AB = AddName<{a: 88, b: 21}, 'Name'>;
    
    /* type AB = {
        aName: 88;
        bName: 21;
    }*/
    

    Playground