Underscore Typing in the Style of Scala

Just for kicks, I started tinkering with creating a Scala-inspired underscore in typescript. I aim to simplify writing code by replacing .map(x => x.myProp) with just .map(_.myProp). The logic behind this is quite simple using Proxies, but the challenge lies in typing.

type Rec<T extends object, K extends keyof T> = T[K]

export const _ = new Proxy<
  Record<string, <T extends object, K extends keyof T>(o: T) => Rec<T, K>>
>(
  {},
  {
    get(target: any, p: string) {
      return <T extends object, K extends typeof p & keyof T>(obj: T) => obj[p as K] as Rec<T, K>
    }
  }
)

This setup allows me to correctly pass the type through map in the subsequent chain, but I struggle to narrow down the myProp type:

https://i.sstatic.net/xDqFw.png

And that's where I hit a roadblock. I thought of potentially typing the Proxy with <any extends infer R ? R: never>, however, then the R cannot be used to refine the property in the get handler.

Any suggestions?

Edit:

Included a playground example

In the second identity map x turns out to be string | number instead of 'string'. When changing the first map to _.id, x should only be number

Answer №1

Here's an alternative approach using the syntax (...) instead:

function getPropertyValue<K extends string>(key: K) {
  return <V>(obj: Record<K, V>) => obj[key];
}

This method is straightforward and effective.

Interactive Demo

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the best ways to increase the speed of eslint for projects containing a high volume of files

My git repository contains around 20GB of data, mainly consisting of JSON/CSV/YAML files. Additionally, there are scattered TypeScript/JavaScript (.ts/.js) files among the data files. As the repository has grown in size, I encounter a significant delay eve ...

Deactivate the selection option in Syncfusion NumericTextbox

I have integrated an Angular NumericTextbox component from Syncfusion into my application. A problem we encountered is that when the input is clicked, it automatically gets selected. Is there a way to disable this behavior? Problem: https://gyazo.com/a72b ...

Unable to perform typescript testing due to syntax errors in mocha

I have configured my mocha test command as follows: mocha --require test/ts-node-hooks.js test/**/*.spec.ts Additionally, here is my ts-node-hooks.js file: const path = require('path'); require("ts-node").register({ project: path.resolve(_ ...

What are some methods for altering ReadOnly values?

I am encountering an issue with the value fetchOptions: Readonly<HttpFetchOptionsWithPath> and my attempt to overwrite one of its properties. Here is the method I have tried: ((fetchOptions as Writable<HttpFetchOptionsWithPath>).headers as Wr ...

Unable to set up Typescript: The package v1.2.3 cannot meet the peerDependency requirements of its siblings

While attempting to set up Typescript for compiling my Angular2 app, I encountered an error message stating "The package [email protected] does not meet the peerDependencies requirements of its siblings." ...

In TypeScript, the choice between using `private readonly` within a class and

I have been contemplating the best method and potential impacts of referencing constants from outside a class within the same file. The issue arose when I was creating a basic class that would throw an error if an invalid parameter was passed: export cla ...

Unraveling the mysteries of the spread operator in Javascript

Having trouble finding the right keyword to search for my issue, as I am confused about JavaScript or TypeScript spread operator behavior. I encountered this problem while working on a drag and drop function today, but let me provide a simple example. Imag ...

How can we access child components in vanilla JavaScript without using ng2's @ViewChild or @ContentChild decorators?

Recently, I delved into the world of using ViewChildren and ContentChildren in Angular 2. It got me thinking - can these be implemented in ES6 without TypeScript annotations? The TypeScript syntax, according to the official documentation, looks something ...

Implementing dynamic display of div based on dropdown selection in typescript

A solution is needed to display or hide specific div elements based on a dropdown selection using Typescript. Sample HTML file: <select class="browser-default custom-select"> <option selected>single</option> <option value="1"> ...

Can an entire object be bound to a model in an Angular controller function?

In TypeScript, I have defined the following Interface: interface Person { Id: number; FirstName: string; LastName: string; Age: number; } Within a .html partial file, there is an Angular directive ng-submit="submit()" on a form element. A ...

Is it possible to create an Angular 2 service instance without relying on the constructor method?

I'm struggling to utilize my ApiService class, which handles API requests, in another class. Unfortunately, I am encountering a roadblock as the constructor for ApiService requires an HttpClient parameter. This means I can't simply create a new i ...

Using Typescript to determine the data types based on the specific object keys

Imagine having a type defined as: type Foo = { foo: number; bar: string; baz: boolean; } The goal is to create a type Buzz that can determine the value type for a specific key, such as: const abc: Buzz<Foo> = { key: 'foo', form ...

Utilize RequireJS to load and initiate the primary ViewModel written in TypeScrypt

Recently, I started using requireJs and I'm facing a challenge. I want to load a viewmodel from my main script, App.ts, and retrieve a new instance of my viewModel: LienPdtUfActVM.ts. This is how my App.ts file looks like: declare var jQuery: JQueryS ...

Challenge with TypeScript typing (slightly connected to (P)React)

[Update: I've revised my initial query] Let's say I aim to specify UI components in the exact manner outlined below (the following lines are non-negotiable - any solution that alters these lines is not what I'm seeking): // Please refrain ...

What is the process for configuring React on one server and springboot on a separate server?

Can you help me with the setup of the following: Web Server : I need to set up a react + typescript application using npm at Backend Server : I also need to configure a Springboot backend server at I am currently using webpack to build the react applica ...

What are the reasons behind my decision not to utilize the correct Card component in React Bootstrap?

I am new to using react. I am attempting to utilize the Card component from bootstrap in the following way: import React from "react"; import { Card, Button } from "@material-ui/core"; const PortfolioSection: React.FC = () => { r ...

Updating the dropdown option value in Angular 10's edit component

In my Angular and ASP.NET application, I have an edit form in a component with multiple select options in a dropdown list. When displaying all data in the edit form, the dropdown list fields are displayed as empty instead of showing the previously stored v ...

In Typescript, it is not permitted to assign a variable as a value within a styled array

Encountering a peculiar issue with TypeScript, Emotion.css, and React. The following code functions without any issues: import styled from '@emotion/styled-base'; const Layout = styled('div')([ { height: 48, color: ...

Automatic Formatting of Typescript in SublimeText

Utilizing Microsoft's Typescript Sublime Plugin, I am able to format a file using the shortcut ^T ^F as outlined in the plugin's feature list. Is there a method to automatically execute this command when saving a file? Similar to the functionali ...

What is the proper way to implement a function with a value formatter when the column definition is already predefined within quotation marks in AG-Grid?

When working with JSON data that specifies columnDefs and uses valueFormatters as a function, it is essential to correctly format the valueFormatter. For instance, if the JSON data reads valueFormatter: "dateFormatter" instead of valueFormatter: ...