How can one determine the data type by analyzing the key value?

I'm attempting to determine the return type of getAllRaces() as () => Race[].

Here is what I have tried so far:

type CollectionMap = {
    races: Race[]
    horses: Horse[]
}

type Race = {
    date: Date
}

type Horse = {
    name: string
}

type UnionizeKeys<T> = {
    [k in keyof T]: k
}[keyof T]

type CollectionName = UnionizeKeys<CollectionMap> // "races" | "horses"

// Unsuccessful attempts

const getAll1 = (name: CollectionName) =>  [] as CollectionMap[name];
// 💥 Type 'name' cannot be used as an index type.(2538)

const getAll2 = (name: CollectionName) =>  [] as CollectionMap[typeof name as const];
// 💥 A 'const' assertions can only be applied to references to enum members,
//    or string, number, boolean, array, or object literals.(1355)

const getAll = (name: CollectionName) =>  [] as CollectionMap[typeof name];

const getAllRaces = () => getAll('races')
// ❌ const getAllRaces: () => Race[] | Horse[]
// ✅ const getAllRaces: () => Race[]

TypeScript Playground

Thank you for your assistance.

Answer №1

If you wish for the return type of getAll() to be determined by the input name, you can introduce a generic parameter K representing the type of name. This parameter K is then constrained to keyof CollectionMap (equivalent to your CollectionName type, but more explicitly defined than UnionizeKeys):

const getAll = <K extends keyof CollectionMap>(
    name: K
): CollectionMap[K] => [];

The return type becomes the indexed access type CollectionMap[K], which represents the property in CollectionMap with the key of type K.

Let's test this:

const getAllRaces = () => getAll('races')
// const getAllRaces: () => Race[]
const getAllHorses = () => getAll('horses');
// const getAllHorses: () => Horse[]

Seems to be working as intended.

Link to Playground for testing code

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

Is the parameter rejecting the use of orderBy for 'startTime'?

Hey there! I'm currently working on an AngularJS project in TypeScript that involves integrating Google API to fetch Google Calendar events. The syntax for making a call is specified in the documentation available at: https://developers.google.com/goo ...

The stack property of [object Object] cannot be updated, as it only has a getter method

I can't figure out why I'm receiving this specific error in the Plunker below. Cannot set property stack of [object Object] which has only a getter Access the Plunker here: https://plnkr.co/edit/IP1ssat2Gpu1Cra495u2?p=preview The code causi ...

Encountering TypeScript errors while trying to implement Headless UI documentation

import { forwardRef } from 'react' import Link from 'next/link' import { Menu } from '@headlessui/react' const MyLink = forwardRef((props, ref) => { let { href, children, ...rest } = props return ( <Link href={href}&g ...

Having trouble getting @types/express-session to function properly. Any suggestions on how to fix it?

My web-app backend is built with TypeScript and I've integrated express-session. Despite having @types/express and @types/express-session, I continue to encounter type errors that say: Property 'session' does not exist on type 'Request ...

Send the template to the enclosed grid column

I enclosed a kendo-grid-column within a new component by using <imx-gridColumn field="Count" title="Count"> ... </imx-gridColumn> The component that includes the imx-gridColumn is templated with <kendo-grid-column #column field="{{field}} ...

What is the best way to inject services into non-service class instances in Angular 2?

Here is my current approach, but I'm curious about the recommended practice for working with Angular2? ... class MultitonObject { _http: Http; constructor (appInjector: Injector) { this._http = appInjector.get(Http); } } var ap ...

Using Angular DI to inject a specific token value into a provider factory

Can an InjectionToken be injected into a factory provider? This is what I have implemented: export const HOST_TOKEN = new InjectionToken<string>("host"); let configDataServiceFactory = (userService: UserService, host: string) => { return ne ...

The technique for concealing particular div elements is contingent upon the specific values within an array

My TypeScript code is returning an array in this format: allFlowerTypes (3) ['Rose', 'Bluebell' , 'Daisy'] I want to dynamically show or hide the following HTML content based on the array values above: <ul> <li> ...

Can someone confirm if I am importing this png file correctly? I am encountering an error with Vite, here is my code

Error: TypeScript+ React + Vite [plugin:vite:import-analysis] Failed to find import "./assets/heropic.png" in "src\components\Hero.tsx". Are you sure the file exists? Hello fellow developers! I am new to working with react and typescript. Curren ...

Exploring the customization options for Prime NG components is a great way to

Currently, I am working on a project that involves utilizing Prime NG components. Unfortunately, the p-steps component does not meet one of our requirements. I am looking to customize the Prime NG p-steps component to fit our needs. Is there a way to cre ...

OpenTok Angular 6 encountered an error with code TS2314 stating that the generic type 'Promise<T>' needs to have 1 type argument specified

Issue in opentok.d.ts File: Error TS2314 npm version: 6.2.0 node: v8.10.0 Angular CLI: 6.2.3 Operating System: Linux x64 Angular Version: 7.0.0-beta.5 @opentok/client": "^2.14.8 ...

I am interested in creating a checkbox filtering system using Angular

Below is the display from my project's output window view image description here In the image, you can see checkboxes on the left and cards on the right. I want that when a checkbox is checked, only the corresponding data should be shown while the r ...

The button will be disabled if any cells in the schedule are left unchecked

I am seeking help on how to dynamically disable the save button when all checkboxes are unchecked. Additionally, I need assistance with enabling the save button if at least one hour is selected in the schedule. Below is my code snippet for reference: htt ...

What is the process for importing files with nested namespaces in TypeScript?

Currently, I am in the process of transitioning an established Node.js project into a fully TypeScript-based system. In the past, there was a static Sql class which contained sub-objects with MySQL helper functions. For instance, you could access functions ...

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 ...

Ensuring precise type inference in generic functions using the keyof keyword

I am facing a challenge in creating a versatile function that accepts an object and a key from a specific subset of keys belonging to the type of the object. These keys should correspond to values of a specified type. This is how I attempted to implement ...

When running on localhost, IE11 only shows a white screen while the other browsers function properly

I have recently completed a web-based project and successfully deployed it. The project is running on port 8080. Upon testing in Chrome, Safari, and Firefox, the project functions without any issues, and no errors are displayed in the console. However, wh ...

Broaden the scope of a `Record<string, string[]>` by adding a new type of property

When working in Typescript, it appears that defining the type as shown below should create the desired outcome: interface RecordX extends Record<string, string[]> { id: string } However, an error is thrown stating: Property 'id' of t ...

Encountering an error message stating "The variable 'App' is declared but not used" when running the index.tsx function

This React project is my attempt to learn how to use a modal window. The tutorial I've been following on YouTube uses JavaScript instead of TypeScript for their React project. However, I'm facing some challenges. Could you possibly help me ident ...

When working with TypeScript, how do you determine the appropriate usage between "let" and "const"?

For TypeScript, under what circumstances would you choose to use "let" versus "const"? ...