Key Remapping with as

Rename or filter keys inside a mapped type — reshape objects at the type level.

Inside a mapped type you can rewrite each key with an as clause: { [K in keyof T as NewKey]: ... }. Combined with template literal types, this lets you rename keys wholesale.

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
// { name: string } -> { getName: () => string }

Filtering keys

Remap a key to never and it disappears from the result. That turns key remapping into a filter — keep only the properties whose value type matches some condition:

type OnlyStrings<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K]
};

Renaming plus filtering makes mapped types a genuine object-reshaping toolkit, not just a decorator.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • A mapped type renames every property in an interface to a camelCase getter name by prefixing 'get'.
  • A filter remaps only properties matching a specific value type by using never to drop unwanted keys.
  • An event handler map derives property names by prepending 'on' and capitalising the original key.

More examples

Remap keys with as

The as clause renames each key K to a getter-style name using a template literal with Capitalize, producing typed accessor methods.

Example · ts
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface User { name: string; age: number; }
type UserGetters = Getters<User>;
// { getName: () => string; getAge: () => number }

Filter keys with never

Remaps keys to never when their value type is not string, which removes those keys from the resulting mapped type.

Example · ts
type OnlyStrings<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K];
};

interface Mixed { name: string; age: number; active: boolean; email: string; }
type StringOnly = OnlyStrings<Mixed>;
// { name: string; email: string }

Prefix and filter combined

Combines key remapping with a string constraint and Capitalize to generate typed event handler signatures from a form schema.

Example · ts
type EventHandlers<T> = {
  [K in keyof T as K extends string ? `on${Capitalize<K>}` : never]:
    (value: T[K]) => void;
};

interface FormFields { name: string; age: number; }
type FormEvents = EventHandlers<FormFields>;
// { onName: (value: string) => void; onAge: (value: number) => void }

Discussion

  • Be the first to comment on this lesson.
Key Remapping with as — TypeScript | SoundsCode