387

Is key-value pair available in TypeScript? If so, how do I do that? Can anyone provide sample, example, or links?

2
  • 1
    yes it is,can u specify your requirement ? Commented Apr 7, 2016 at 5:36
  • typescript transpiles(not compile) into javascript, so all feature of javascript is available in typescript. e.g. if you write your code in js and change its extension to .ts, it will work as fine as your js code. learn more about it on :- typescriptlang.org/docs. Commented Apr 7, 2016 at 7:51

14 Answers 14

556

Is key-value pair available in Typescript?

Yes. Called an index signature:

interface Foo {
   [key: string]: number;
}


let foo:Foo = {};
foo['hello'] = 123;
foo = {
  'leet': 1337
};
console.log(foo['leet']); // 1337

Here keys are string and values are number.

More

You can use an es6 Map for proper dictionaries, polyfilled by core-js.

Sign up to request clarification or add additional context in comments.

7 Comments

This is a map or dictionary. If you want something equivalent to a C# KeyValuePair, see answer stackoverflow.com/questions/36467469/…
Also nice to know, you don't need to call it key. You can, for instance, also write this: [countryCode: string]: string. Nice for readability.
Yes, this is a map. But every time I search for "TypeScript Map," all I get is es6 Map, which is not what I want! So I'm very thankful that this answer is here.
you saved me <3
|
261

The simplest way would be something like:

var indexedArray: {[key: string]: number}

Usage:

var indexedArray: {[key: string]: number} = {
    foo: 2118,
    bar: 2118
}

indexedArray['foo'] = 2118;
indexedArray.foo= 2118;

let foo = indexedArray['myKey'];
let bar = indexedArray.myKey;

4 Comments

This helped a lot - Less code than the interface approach because it doesn't require describing Bar
Have you got an example usage of this?
indexedArray = {}; indexedArray["one"] = 1; /* good */ indexedArray["two"] = "two"; / fails */
Best answer. Least confusing with simple data types
78

You can also consider using Record, like this:

const someArray: Record<string, string>[] = [
    {'first': 'one'},
    {'second': 'two'}
];

Or write something like this:

const someArray: {key: string, value: string}[] = [
    {key: 'first', value: 'one'},
    {key: 'second', value: 'two'}
];

Comments

42

Is key-value pair available in Typescript?

If you think of a C# KeyValuePair<string, string>: No, but you can easily define one yourself:

interface KeyValuePair {
    key: string;
    value: string;
}

Usage:

let foo: KeyValuePair = { key: "k", value: "val" };

6 Comments

Somewhat funny, already 6 votes with a sum of 0. Would the downvoters mind adding a comment what is bad about this solution?
I too would like to know. Down voters never leave a comment, I sometimes think because they themselves don't know any better solution.
I didn't downvote but this solution doesn't have add, get, remove, etc.
@DaNeSh That is right. A KeyValuePair is not a list, but it could be an entry of a list. Maybe you are looking for a List<>? See stackoverflow.com/questions/23096260/…
A KeyValuePair is not a list. There is just a single key and a single value within. Key: foo.key and value: foo.value. It seems your are looking for a List<> --> stackoverflow.com/questions/23096260/…
|
21

Another simple way is to use a tuple:

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10];
// Access elements
console.log("First: " + x["0"] + " Second: " + x["1"]);

Output:

First: hello Second: 10

Comments

19

Not for the questioner, but for all others, which are interested: See: How to define Typescript Map of key value pair. where key is a number and value is an array of objects

The solution is therefore:

let yourVar: Map<YourKeyType, YourValueType>;
// now you can use it:
yourVar = new Map<YourKeyType, YourValueType>();
yourVar[YourKeyType] = <YourValueType> yourValue;

Cheers!

6 Comments

Where is Map defined? Is it Angular-specific?
yourVar[YourKeyType] = XXX. This does not set an element in the Map. It does set a property.
IE browser doesn't support Map, any alternative?
@RahulUpadhyay Drop IE? :D
|
14

A concise way is to use a tuple as key-value pair:

const keyVal: [string, string] =  ["key", "value"] // explicit type
const keyVal2 = ["key", "value"] as const // inferred type with const assertion
const [key, val] = ["key", "val"] // usage with array destructuring

You can create a generic KeyValuePair type for reusability:

type KeyValuePair<K extends PropertyKey, V = unknown> = [K, V]
const kv: KeyValuePair<string, string> = ["key", "value"]

TS 4.0

provides labeled tuple elements for better documentation and tooling support:

type KeyValuePairNamed = [key: string, value: string] // "key" and "value" labels

Compatibility

[key, value] tuples also ensure compatibility to JS built-in objects:

Playground

2 Comments

how do I use this KeyValuePairNamed?
Just write const kvp: KeyValuePairNamed = ["mykey", "myval"]. The labels are a type-only construct for documentation purposes.
13

an example of a key value pair is:

[key: string]: string

you can put anything as the value, of course

2 Comments

export default interface KeyValuePair { [key: string]: string | number | boolean; } Is slightly better, but is this weak typing? Does this defeat the purpose to some extent?
Yes but when you have array of those like newRows: { [key: string]: string; }[] then filter wont work this.newRows = this.newRows.filter(x=>x.length>0) Operator '>' cannot be applied to types 'string' and 'number'.ts(2365) x is an item of the array to supposed to be an array itself. Any ideas?
5

One can also simple use Record

type Foo = Record<string, number>

Further usage in the docs

Comments

4
class Pair<T1, T2> {
    private key: T1;
    private value: T2;

    constructor(key: T1, value: T2) {
        this.key = key;
        this.value = value;
    }

    getKey() {
        return this.key;
    }

    getValue() {
        return this.value;
    }
}
const myPair = new Pair<string, number>('test', 123);
console.log(myPair.getKey(), myPair.getValue());

2 Comments

This is not helpfull if you're trying to type data coming from the backend.
@MathijsSegers This class is not meant to be a concrete type. Use this class as a derived type into your concrete type
3

KeyValue interface exists in angular library that uses typescript. So you have this generic interface to use if your project is angular. Or you can use its declaration to get a nice generic KeyValue interface if you are not using TS in angular.

enter image description here

export declare interface KeyValue<K, V> {
    key: K;
    value: V;
}

3 Comments

What about those who don't use Angular?
@fdrobidoux generally for typescript you will see, eg, Record<string, number> (simply replace "KeyValue" with "Record".
good one for angular. Instead of making custom class
1

TypeScript has Map. You can use like:

public myMap = new Map<K,V>([
[k1, v1],
[k2, v2]
]);

myMap.get(key); // returns value
myMap.set(key, value); // import a new data
myMap.has(key); // check data

Comments

0
const YAHOO = 'YAHOO';
const GOOGLE = 'GOOGLE';
const google = 'google';
const yahoo = 'yahoo';

type DomainKeyType = typeof GMAIL | typeof GOOGLE;
type DomainValueType = typeof google | typeof yahoo;

type DomainType = Record<DomainKeyType , DomainValueType>

const domain: DomainType = {
  YAHOO: yahoo,
  GOOGLE: google,
}

Comments

-1

If you are trying to use below example

Example: { value1: "value1" }

And add conditionalData dynamically based on some condition, Try

let dataToWrite: any = {value1: "value1"};

if(conditionalData)
   dataToWrite["conditionalData"] = conditionalData

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.