Index signatures in TypeScript are a nice way to open up a type for unknown fields. This might be useful if you don’t know all the attributes in advance. In contrast, as a developer, you typically want a strict type so that your code editor can infer the type of a value. You want IntelliSense in your editor and the guiding hand during development.
This tutorial shows you how to remove the index signature from a TypeScript type.
TypeScript Series Overview
- How to Export Transpiled Code From package.json
- Use Nodemon to Restart Your Server on Changes
- How to Allow Trailing Commas (Comma-Dangle) With Typescript-ESLint
- Use SWC to Speed up TypeScript Code
- Fixing Null Type Ignored in Union Type
- How to Remove Index Signature from a Type
- Module Augmentation Overwrites Declarations Instead of Merging Them
- Get All Keys of an Enum
- Get All Values of an Enum
- Using a String as Enum Key
- Understanding “keyof typeof”
- Get Type of Class Properties and Omit Methods
Removing the Index Signature from a Type in TypeScript
TypeScript comes with a feature called Key Remapping in Mapped Types. It allows you to re-map keys using an as
clause. This is helpful for the removal of index signatures. When removing an index signature, you know that the key of such an index signature is either of type string
, number
, or symbol
.
Let’s look at a Person
interface that has two specific keys name
and age
and the index signature:
export interface Person {
name: string
age: number
[key: string]: any
}
The broad index signature opens up the values for keyof Person
to string
. What you actually want is that keyof Person
is strictly resolving to 'name'
and 'age'
. That’s achievable by removing the index signature. Here’s a StrictlyTypedPerson
with a removed index signature and only keeping the specific keys known in the Person
interface:
export interface Person {
name: string
age: number
[key: string]: any
}
type StrictlyTypedPerson = {
// copy all attributes from the person interface
// and remove the index signature
[K in keyof Person as string extends K
? never
: number extends K
? never
: K
]: Person[K];
};
// type StrictlyTypedPerson = { name: string, age: number }
The way removing the index signature works is this: we’re going through every key in the Person
interface. If the type detects a broad string
key, it resolves the type to never
which tells TypeScript to remove it. The same holds true for the number
type.
You might wonder why the resulting type keeps the name
and age
attributes. Good catch! The name
and age
keys resolve to the exact, same-named keys 'name'
and 'age'
instead of a broad „string“ type. That means, name
and age
stay in the type.
Creating a Generic Type to Remove the Index Signature
You could also extract the type removing the index signature to a generic, reusable type:
export type RemoveIndexSignature<T> = {
[K in keyof T as string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K
]: T[K];
}
You can use the generic RemoveIndexSignature
type like in this example: create a strict Person
type with known properties:
export interface Person {
name: string
age: number
[key: string]: any
}
type StrictlyTypedPerson = RemoveIndexSignature<Person>
// type StrictlyTypedPerson = { name: string, age: number }
Enjoy removing index signatures from TypeScript types!