Verify the specific type conditions of a key value in a mapped type

I am attempting to achieve the following:

If the actions property exists, and there are callbacks within the actions properties that return a string, then return X or Y.

The above code is expressed as:

// type MappedType<T> = {
//   [K in keyof T]: T[K] extends () => string ? T[K] : never
// }

// it should check if the object has the property actions and also check if properties within actions are callbacks that return a string

type HasStringReturn<Options> = Options extends { actions: { [K in keyof Options]: Options[K] extends () => string ? Options[K] : never } } ? Options: 'Something went wrong';



type StringCallback = {
  actions: {
    test: () => 'i love owls i really do.'
  }
}


type FinalCheck = HasStringReturn<StringCallback>

Currently, it returns "Something went wrong" even though the type is correct. Maybe I am missing something.

I am just trying to check for the existence of actions, and within actions check if the properties are callbacks that return a string. That's pretty much it.

Is this where I have to use infer or would a generic conditional be sufficient? Curious to know. Thanks.

Playground link

Answer №1

Your current version has a flaw in checking Options instead of Options["actions"] for function properties. To correct this, consider using conditional type inference to assign a type parameter name to Options["actions"]. Here's an example:

type HasStringReturn<T> =
  T extends { actions: infer A } ?
  A extends { [K in keyof A]: A[K] extends () => string ? A[K] : never } ? T :
  "something went wrong" :
  "something continued to go wrong";

(Note the change from Options to T for better type parameter naming conventions). This involves two checks, each capable of triggering the error condition. First, it verifies if T possesses an actions property, then if that actions property aligns with the correct type.

Let's test its functionality:

type StringCallback = {
  actions: {
    test: () => 'i love owls i really do.',
  }
}
type Good = HasStringReturn<StringCallback>
/* type Good = {
    actions: {
        test: () => 'i love owls i really do.';
    };
} */

type BadStringCallback = {
  actions: {
    test: () => 'i love owls i really do.',
    oops: number
  }
}
type Bad = HasStringReturn<BadStringCallback>;
// type Bad = "something went wrong"

type ReallyBadStringCallback = { test(): string }
type ReallyBad = HasStringReturn<ReallyBadStringCallback>;
// type ReallyBad = "something continued to go wrong"

Success!

Access the code on the Playground

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

How to redefine TypeScript module export definitions

I recently installed a plugin that comes with type definitions. declare module 'autobind-decorator' { const autobind: ClassDecorator & MethodDecorator; export default autobind; } However, I realized that the type definition was incorrec ...

Combining a pair of canvases

Currently, I am utilizing a JavaScript library to create a QR Code. This library generates the QR code by displaying it on a canvas. Nevertheless, my goal is to integrate a background behind this QR Code. I attempted to achieve this by first drawing the b ...

The statement 'typeof import("...")' fails to meet the requirement of 'IEntry' constraint

When trying to run npm run build for my NextJS 13 app, I encountered the following type error: Type error: Type 'typeof import("E:/myapp/app/login/page")' does not satisfy the constraint 'IEntry'. Types of property 'def ...

Issue encountered with connecting to development server on Expo iOS simulator that is not present when using a browser

During the development of a chat application with React Native Expo, I encountered an issue when running "expo start" in my typical workflow. The error message displayed was "could not connect to development server." If anyone has experienced a similar pr ...

Exploring nested contexts in react testing library with renderHook

This is a sample code snippet in TypeScript that uses React and Testing Library: import React, { FC, useEffect, useMemo, useState } from 'react'; import { renderHook, waitFor } from '@testing-library/react'; interface PropsCtx { inpu ...

InitAuth0 Auth0 encountering deepPartial error in Next.js with TypeScript setup

Having some trouble setting up auth0 with nextjs using typescript. When I try to initialize Auth0, I encounter an error regarding deep partials, Argument of type '{ clientId: string; clientSecret: string; scope: string; domain: string; redirectUri: st ...

Exploring the use of .pipe with Angular Jest for testing

Currently, I am trying to test the following .ts file: create(entityResourceID, params: any): Observable <any>{ const url = `${this.apiUrl}/${entityResourceID}/assignee`; return this.http.post(url, params).pipe( map(() ...

Error encountered when asynchronously iterating over an object in TypeScript

Could someone please help me understand why I am getting an error with this code? var promise = new Promise((resolve, reject) => { resolve([1, 2, 3, 4, 5]); }); async function doSomethingAsync() { var data = await promise; data.forEach(v = ...

What causes different errors to occur in TypeScript even when the codes look alike?

type Convert<T> = { [P in keyof T]: T[P] extends string ? number : T[P] } function customTest<T, R extends Convert<T>>(target: T): R { return target as any } interface Foo { x: number y: (_: any) => void } const foo: Foo = c ...

Removing an object from an array when a certain key value already exists in TypeScript

I'm currently facing an issue with my function that adds objects to an array. The problem arises when a key value already exists in the array - it still gets added again, but I want it to only add if it doesn't exist yet. Here's what I have: ...

Troubleshooting property assignment issues within an Angular service

I have created a simple injectable service in TypeScript for Angular 4. This service is designed to fetch a JSON file from the network and store the data as an array in its property called data. Other classes can then access this data using the method getD ...

Vite encounters issues when using PNPM because of import analysis on the `node_modules/.pnpm` package

When utilizing PNPM and Vite in a monorepo, I encountered a perplexing issue. The email addresses appearing like `<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c0b6a9b4a580f4eef4eef9">[email protected]</a>_@<a ...

What is the best way to transition a connected component from a class-based to a functional component in TypeScript?

I'm in the process of switching from a class-based component to a functional component. This is a connected component that uses mapState. Here is my initial setup: import { connect } from 'react-redux' import { fetchArticles } from '. ...

Angular Appreciation Meter

Looking to create a rating system using Angular. The square should turn green if there are more likes than dislikes, and red vice versa (check out the stackblitz link for reference). Check it out here: View demo I've tried debugging my code with con ...

.bail() function does not function properly when used in conjunction with express-validator

While registering a new user, I require their name, email, and password. If no name is provided, there is no need for the backend to validate the email. I believe that the use of .bail() in express-validator should handle this situation, but unfortunately ...

Why does the ReactJS MaterialUI Modal fail to update properly?

Recently, I encountered a curious issue with my Modal component: https://i.stack.imgur.com/dkj4Q.png When I open the dropdown and select a field, it updates the state of the Object but fails to render it in the UI. Strangely, if I perform the same action ...

Troubleshooting a Type Parameter Error in React Native TypeScript

I am working on a project in React Native using TypeScript, and I encountered this issue: I am getting the error Argument of type 'GestureResponderEvent' is not assignable to parameter of type 'SetStateAction<string>'.ts(2345) wit ...

Avoid using propTypes for props verification

Looking for a solution to handle multiple props on a button: interface buttonProps { secondary?: boolean; tertiary?: boolean; width?: number; children?: any; icon?: string; } If the button includes an icon without any children, how can ...

Substitute data types for certain keys within a Typescript interface

Within this code snippet, the goal is to create a new type from an existing one by iterating through the keys and only replacing those that meet a specific condition. Additionally, union types are being utilized here. class A {} class B { constructor ...

Deactivate the rows within an Office UI Fabric React DetailsList

I've been attempting to selectively disable mouse click events on specific rows within an OUIF DetailsList, but I'm facing some challenges. I initially tried overriding the onRenderRow function and setting CheckboxVisibility to none, but the row ...