Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In TypeScript is it possible to define dynamic properties that follow a pattern?

Tags:

typescript

In TypeScript is it possible to define dynamic properties that follow a pattern?

Let me demonstrate what I'm asking. I know that you can set up an interface or type that uses dynamic properties in a few ways, for example:

interface MyInterface {
  [key: string]: string
}

type MyType = Record<string, string>

What I'm looking for is something that only applies the type for properties that match a specific pattern. So if I wanted to apply a type the properties that only started with "str" and another type to properties that started with "num" I might do something like this:

interface MyInterface {
  [key: /^str/]: string
  [key: /^num/]: number
}

This interface would then allow you to do this:

const o: MyInterface = {
  strFirstName: 'Jay',
  strLastName: 'Jones',
  numAge: 86
}

Does anything like that exist in TypeScript or does anyone know of a way to make that work?

like image 275
James Avatar asked Oct 28 '25 14:10

James


1 Answers

Yes, starting in TypeScript 4.4 you will be able to use pattern template literal strings in index signatures as implemented by microsoft/TypeScript#44152. So your MyInterface will be written like this:

interface MyInterface {
  [key: `str${string}`]: string
  [key: `num${string}`]: number
}

And you can verify that it works the way you want:

const o: MyInterface = {
  strFirstName: 'Jay',
  strLastName: 'Jones',
  numAge: 86
}; // okay

const oops: MyInterface = {
  strFine: "okay"  
  strWrongType: 456, // error!
  //~~~~~~~~~~
  //Type 'number' is not assignable to type 'string'.  
  numFine: 789,
  numWrongType: "oops"
  //~~~~~~~~~~
  //Type 'string' is not assignable to type 'number'.(2322)
}

Right now (2021-06-24) you can use typescript@next to get access to this feature; or you can wait until TypeScript 4.4 is released on or around 2021-08-24.

Playground link to code

like image 177
jcalz Avatar answered Oct 31 '25 06:10

jcalz