Danilo Ferreira
Danilo Ferreira

Reputation: 80

Type-safe way to transform a key and a value into an object with that single key/value

I want to write a function valueToObject that, given a key and a value, yields an object with that single key and value, e.g.:

valueToObject('myKey', 3);
// should return {myKey: 3}

I tried the following code:

type Wrapped<K extends string, V> = {
  [P in K]: V;
};
function valueToObject<K extends string, V>(key: K, value: V): Wrapped<K, V> {
  return {[key]: value};
}

But this does not compile, unless I cast the return value to any:

error TS2322: Type '{ [x: string]: V; }' is not assignable to type 'Wrapped<K, V>'.

How can I write this function in a type-safe way?

Upvotes: 0

Views: 317

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250326

When using a computed property the type with a generic parameter the type will be inferred to { [name: string]: V }. This seems to be related to this issue, which although is marked as fixed, you can see @jcalz commented about 4 days ago that this is still happening on 2.9.

Edit This issue seems to be a close match and is still open with a target of 3.0 so we may get a fix soon

The only work around is to use a type assertion:

function valueToObject<K extends string, V>(key: K, value: V): Wrapped<K, V> {
    return { [key]: value } as Wrapped<K, V>;
}
//OR
function valueToObject<K extends string, V>(key: K, value: V): Wrapped<K, V> {
    var result = {} as   Wrapped<K, V>
    result[key] = value;
    return result;
}

I suggest you report this on GitHub, or comment on the issue to draw attention to the fact that this still happens.

Upvotes: 3

Related Questions