I am having trouble making this specific type generic. The type "x" is not able to index type "y" ts(2536)

I am currently working on creating a generic type that takes a root-level property name and returns a union type of a property nested underneath it. For instance:

interface operations {
  updateSomething: {
    "201": {
      schema: number;
    };
    "400": {
      schema: string;
    };
  };
}

If I want to retrieve the "schemas" for the type updateSomething, it should result in number | string. The non-generic version functions accurately:

type UpdateSomethingSchema =
  operations["updateSomething"][keyof operations["updateSomething"]]["schema"];

// string | number ✓

In attempting to write a generic type, I encounter this error:

Type '"schema"' cannot be used to index type 'operations[O][keyof operations[O]]'.ts(2536)

Curiously, despite the error message, the type appears to work as intended when implemented:

type UpdateSomethingSchema = SchemaOf<"updateSomething">;

// string | number ✓

Is there an error in my approach, or is this simply a limitation of TypeScript?

Answer №1

To tackle this problem, utilize distributive conditional types in TypeScript:


type Configuration<T> = {
  config: T
}

interface actions {
  performUpdate: {
    "201": Configuration<number>;
    "400": Configuration<string>;
  };
}

type ConfigOf<
  A extends keyof actions
  > = actions[A][keyof actions[A]] extends Configuration<infer C> ? C : never

type Output = ConfigOf<'performUpdate'> // string | number

When actions[A][keyof actions[A]] deduces an object with a config property, TypeScript can infer the type of config: T and due to distributivity, it will yield a union type.

Documentation on Distributive Conditional Types

Answer №2

It's puzzling why TS can't seem to grasp this concept on its own, but there is some skepticism around whether "schema" is actually a key of that object. With a gentle nudge, however, it manages to work things out:

type SchemaType<Obj extends keyof objects> = objects[Obj][keyof objects[Obj]]["schema" & (keyof objects[Obj][keyof objects[Obj]])];

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

Monitoring URL changes in Angular2 using the HostListener

I have a common navbar component that is included in every page of my website. I would like it to detect when the URL changes using a HostListener. @HostListener('window:hashchange', ['$event']) onHashChange(event) { this.checkCu ...

Stop the Decimal in MUI TextField

Having trouble creating a customized Currency Input? You may be experiencing an issue where the textfield prevents the input of decimals. Take a look at the code below for possible solutions. main.ts const [_val, setVal] = React.useState(""); const h ...

Tips for incorporating asynchronous page components as a child element in next.js?

Utilizing the latest functionality in next.js for server-side rendering, I am converting my component to be async as per the documentation. Here is a simple example of my page component: export default async function Home() { const res = await fetch( ...

Having trouble with Angular 2 when submitting a form

Whenever I try to submit a form with two input fields and one select list, the submitted value for the select list is always 0. I am unsure where I am making a mistake. When I post this form to an API, all values are correct except for the select list valu ...

Exclude<Typography, 'color'> is not functioning correctly

Take a look at this sample code snippet: import { Typography, TypographyProps } from '@material-ui/core'; import { palette, PaletteProps } from '@material-ui/system'; import styled from '@emotion/styled'; type TextProps = Omi ...

Retrieving the row value of a checkbox in an Angular table

I'm facing a challenge where I have a table with three columns, one of which is a checkbox. Here is an image for reference: https://i.sstatic.net/4U6vP.png Here is the code snippet: <div nz-row> <nz-table nz-col nzSpan="22" [nzLoading] ...

Encountering the error "tsx is not defined" during a Jest test in a React/TypeScript project

I'm currently working on implementing Jest tests within a React project that has enforced TypeScript settings. In a simple test.tsx file located in the test folder, I have the following code: import React from 'react'; describe('Test& ...

The dynamically rendered component cannot be assigned to the type 'IntrinsicAttributes & ContentOutlineProps & ContentBrainstormProps'

I am facing an issue on my page where a <SideBar /> component is causing a Typescript error with the setActivePage hook. The error message points to a specific line in my code: const Content: (({ question_blocks, }: ContentBrainstormProps) => JSX. ...

Using React.useMemo does not efficiently avoid unnecessary re-renders

In my code, I am working with a simple component as shown below: const Dashboard = () => { const [{ data, loading, hasError, errors }] = useApiCall(true) if (hasError) { return null } return ( <Fragment> <ActivityFeedTi ...

A method for comparing two arrays containing identical objects and then storing the results in a variable

I have an item stored within two other items called formKeyValues and form formKeyValues https://i.stack.imgur.com/nRfiu.png form https://i.stack.imgur.com/eDpid.png I am looking to extract only the keys and values from formKeyValues and place them in ...

An issue occurred: Unable to access the 'name' property because it is undefined

The program is not recognizing the property name. I am using the Input() function and an API to display all tweets from my API. Despite trying various solutions like changing names and properties, it still doesn't work. Is there a simple way to resolv ...

Using TypeScript, one can easily employ a jQuery element within Vue's 'data' option

Is there a way to store a reference of a jQuery element in the Vue 'data' object without causing TypeScript errors? Any suggestions on how to resolve this issue? [EDIT] I managed to work around the TypeScript error by setting a non-existing jQu ...

TypeScript requires that the `includes` function must have the same type parameter for both input and

When working with TypeScript, I've encountered an interesting dilemma regarding the use of the Array.Prototype.includes function. It seems that this function requires me to pass in the same type as in the original array, but isn't the purpose of ...

Tips for arranging TypeScript AST nodes and generating a TypeScript file as the final result

My objective is to reorganize the code in a way that sorts the link(foo) value based on the string text: import Text from '~/text.js' export default function rule(text: Text) { // Sorting rules alphabetically } Although I have made some progr ...

What is the process for assigning a custom React component as the Type for a prop in another component?

Currently, I am working on a customized GenericModal component and would like to include an array of my ModalText components as props in the GenericModal for display purposes. I want to specifically define the type of prop being passed, rather than using s ...

ESLint does not recognize the types from `@vuelidate/core` when importing them

When working with TypeScript, the following import statement is valid: import { Validation, ValidatorFn } from '@vuelidate/core' However, this code triggers an error in ESLint: The message "ValidatorFn not found in '@vuelidate/core' ...

Using TypeScript to access native functions in react-native

Recently, I found myself in need of a basic function to interact with native code. Rather than creating a package, I opted to create the Java files as if they were for a plugin and registered them in MainApplication. As I'm using TypeScript, I am cur ...

The function of TypeScript map is not working properly

Encountering the error message "data.map is not a function" while trying to map data from a REST API request returning JSON data. It appears that the issue may stem from the data structure, as it seems like the returned data should be accessed with data.da ...

"Time" for creating a date with just the year or the month and year

I am trying to convert a date string from the format "YYYYMMDD" to a different format using moment.js. Here is the code snippet I am using: import moment from 'moment'; getDateStr(date: string, format){ return moment(date, 'YYYYMMDD&a ...

Error message indicating that the function 'slice' is not defined for the data variable

I've already searched for solutions to a similar issue, but none of them worked for me. I'm dealing with an object that fetches a list of cities including their names, populations, and states. Here is my HTTP service request: cidadesUrl = 'h ...