Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to map object value types in TypeScript?

Tags:

For example, I have a function of the following form:

function wrap<T>(item: T): W<T> {
}
interface W<T> {
  item: T;
}

Is it possible to write function (mapValues), that will transform given object values by applying this wrap function and return properly typed object? I understand how to write the actual function (lodash's _.mapValues will work fine), but I don't know if it is possible to apply proper types.

Is it possible to write mapValues function so the following will compile?

interface Before {
  a: number;
  b: string;
}

interface After {
  a: W<number>;
  b: W<string>;
}

let obj1: Before = { a: 1, b: "2" };
let obj2: After = mapValues(obj1);

function typecheck_number(arg: number) {}
function typecheck_string(arg: string) {}
typecheck_number(obj2.a.item);
typecheck_string(obj2.b.item);
like image 893
Rogach Avatar asked Dec 22 '17 11:12

Rogach


People also ask

How do I create a Map of types in TypeScript?

Creating a MapUse Map type and new keyword to create a map in TypeScript. let myMap = new Map<string, number>(); To create a Map with initial key-value pairs, pass the key-value pairs as an array to the Map constructor.

What is a mapped object type TypeScript?

A mapped type is a generic type which uses a union of PropertyKey s (frequently created via a keyof ) to iterate through keys to create a type: type OptionsFlags < Type > = { [ Property in keyof Type ]: boolean; };

Is there a Map type in TypeScript?

TypeScript map is a new data structure added in ES6 version of JavaScript. It allows us to store data in a key-value pair and remembers the original insertion order of the keys similar to other programming languages. In TypeScript map, we can use any value either as a key or as a value.

Is object a data type in TypeScript?

object is a type that represents the non-primitive type, i.e. anything that is not number , string , boolean , bigint , symbol , null , or undefined . Argument of type 'undefined' is not assignable to parameter of type 'object | null'.Argument of type 'undefined' is not assignable to parameter of type 'object | null'.


1 Answers

Here's one possible solution:

interface W<T> {
  item: T;
}
function mapValues<T>(obj: T): {[K in keyof T]: W<T[K]>} {
  // implementation
}

Unfortunately, similar recursive approach does not seem to be possible, but there is hope that it will be possible with type constraints from this proposal.

This link was very helpful in arriving to this solution: https://blog.mariusschulz.com/2016/05/31/type-queries-and-typeof-in-typescript

like image 53
Rogach Avatar answered Nov 15 '22 05:11

Rogach