the constant gardener
the constant gardener

Reputation: 135

What is the type for a single key-value pair in Typescript?

In TypeScript I know how to declare a multiple key-value pairs object

{ [key: string]: any }

How can I declare a single key-value pair?

The specific use-case I want to support is a prop that can be an array of either string or a single key-pair object.

For example:

const searchArray = [
  'name', 
  {stats: 'resolution'},
  'uptime',
  {config: 'interface'},
];

At first I thought the solution was simply

Record<string,string>

So the final declaration for my searchArray would be

interface Props {
  (...)
  searchArray: (string | Record<string,string>)[],
}

But I expect it to reject this because I sent two key-pair in an object but it accepts it.

searchArray={[
 'name',
 'bitrate',
 {stats:'resolution', stats:'frameRate'}
]}

It should accept only one key-pair per object. The following should be accepted

searchArray={[
 'name',
 'bitrate',
 {stats:'resolution'}, 
 {stats:'frameRate'}
]}

Thanks!

Upvotes: 1

Views: 4142

Answers (1)

jsejcksn
jsejcksn

Reputation: 33836

AFAIK there's no way to restrict a string-indexed type to having only one property entry, but here are two alternative suggestions:

  1. Use a tuple:

TS Playground

type Entry<Key extends PropertyKey, Value> = [Key, Value];

const searchArray = [
  'name', 
  ['stats', 'resolution'],
  'uptime',
  ['config', 'interface'],
] satisfies (string | Entry<string, string>)[];

  1. Or — slightly more verbose (but perhaps more clear, depending on your perspective) — use an object type with key and value properties:

TS Playground

type Entry<Key extends PropertyKey, Value> = {
  key: Key;
  value: Value;
};

const searchArray = [
  'name', 
  { key: 'stats', value: 'resolution' },
  'uptime',
  { key: 'config', value: 'interface' },
] satisfies (string | Entry<string, string>)[];

See also: generics in the TS handbook

Upvotes: 3

Related Questions