Ways to filter down categories by utilizing a specific attribute

How can we define the function getInterface in a way that the returned type by res is specifically number?

Just to be clear: I am not attempting to write these functions myself; rather, I have an environment where a method exists that returns different objects based on parameters.type, and I'm seeking a solution to properly type them.

interface A {
  tag: 'a'
  do_one: () => number;
}
interface B {
  tag: 'b'
  do_one: () => string;
}
type Interface = A | B
let one = getInterface({ type: 'a' })
let res = one.do_one()

Answer №1

It seems like your question may need some clarification, but from what I understand, you want the getInterface function to take a type and return the corresponding value based on that type.

This can be achieved using either overloads or conditional types:

Example using overloads:

type Interface = A | B

function getInterface(v: { type: 'a' }): A
function getInterface(v: { type: 'b'}): B 
function getInterface(v: { type: 'b'} | { type: 'a'}): A | B {
    return null!
}
let one = getInterface({ type: 'a' })
let res = one.do_one()

Example using conditional types:

interface A {
    tag: 'a'
    do_one: () => number;
}
interface B {
    tag: 'b'
    do_one: () => string;
}
type Interface = A | B

type GetJustTypes = Interface extends infer I ? I extends { tag: infer U } ? { tag: U } : never : never
function getInterface<T extends GetJustTypes>(v: T): Extract<Interface, T>
function getInterface(v: { tag: 'b' } | { tag: 'a' }): A | B {
    return null!
}
let one = getInterface({ tag: 'a' })
let res = one.do_one()

Answer №2

function fetchInterfaceOfTypeA(arg: { type: 'a' }): A;
function retrieveInterfaceOfTypeB(arg: { type: 'b' }): B;

const instanceOne = fetchInterfaceOfTypeA({ type: 'a'} )
const result = instanceOne.performAction()  // The result is a number

Answer №3

Thanks a lot for your assistance! I realize my initial question was quite messy, I should have provided more clarity from the start.

Nevertheless, I was able to successfully determine the correct code snippet -

type FilterTag<T, U> = T extends { tag: U } ? T : never
type Interface<T> = FilterTag<A | B, T>
declare function getInterface<T extends string>(params: { type: T }): Interface<T>

resulting in getInterface({ type 'X' }) always delivering the appropriate interface, with only one union type requiring adjustment when necessary

Answer №4

The issue must be addressed using the do_one() function primarily

getInterface(<someparam>):number{
   do_one():number{
      return 4;
   }
}
let result:number = one.do_one();

Answer №5

It is vital to have a clear understanding of typings, as they serve the purpose of preventing errors during compilation. Once compiled, the final outcome will always be pure javascript.

In response to your inquiry, typing can only be inserted using either the or | condition, which is verified solely during compilation.

The concept of dynamic typing remains an unsolved mystery.

However, there is a technique known as instance-of that can be utilized.

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

Comparison of env.local and String variables

I encountered an access denied error with Firebase. The issue seems to arise when I try passing the value of the "project_ID" using an environment variable in the backend's "configs.ts" file, as shown in the code snippet below: import 'firebase/f ...

Creating spec.ts files for components by hand: A guide

Currently, I am facing an issue where the automatic generation of spec.ts files has been disabled by the developers when they created the components. To address this, I manually created the spec.ts files by copying over an existing one into each component, ...

Transforming an ordinary JavaScript object into a class instance

As I was delving into Angular's documentation on "Interacting with backend services using HTTP", I came across the following statement in the "Requesting a typed response" section: ...because the response is a plain object that cannot be automatical ...

Angular EventEmitter coupled with Callbacks

In order to create a custom button component for my angular application and implement a method for click functionality, I have the following code snippet: export class MyButtonComponent { @Input() active: boolean = false; @Output() btnClick: EventEmit ...

What is the best way to define a general class within the constructor of another class in TypeScript?

Is there a way to inject a subclass into a class during its constructor using TypeScript? I've tried to demonstrate my idea with some pseudo-code here: type GenericConstructor<T> = { new (): T; } class MyClass { constructor( SubClass: G ...

Prisma - Modify a single resource with additional criteria

Is it feasible to update a resource under multiple conditions? Consider the tables below: +----------+----------+ | Table1 | Table2 | +----------+----------+ | id | id | | param1T1 | param1T2 | | param2T1 | param2T2 | | idTable2 | ...

Using Typescript and ThreeJS, include new elements to the environment within the loader

Can someone help me with the following code snippet? export class LandingPageComponent implements OnInit { scene: THREE.Scene; (...) ngOnInit() { this.scene = new THREE.Scene(); var loader = new THREE.JSONLoader(); loader.load("../../assets/fire_lion.j ...

Exploring/Adjusting an RxJS Observable Object

I'm currently working with a typescript method that looks like this: private processRequest<T>(request: Observable<T>, ...): Promise<T> {...} request is an HttpClient Observable processRequest(httpClient.get(url, ...)); ... processR ...

Creating JPEG images with specified dimensions. How can you add W x H sizing to an image?

I have been searching for a Deno/TypeScript code snippet that can create basic images with dimensions embedded on them. I have provided an example of the code below, which generates images in JPEG format, base64, and dataURL. The code works by adding RGB ...

Encountering difficulty in retrieving the outcome of the initial HTTP request while utilizing the switchMap function in RxJS

My goal is to make 2 HTTP requests where the first call creates a record and then based on its result, I want to decide whether or not to execute the second call that updates another data. However, despite being able to handle errors in the catchError bl ...

Typescript fails to recognize a value assigned within an await statement

Looking at the code snippet below, we see that the variable x starts off undefined and can later be assigned a value of 1 within an `await` promise. Despite setting x to 1 inside the awaited promise, TypeScript still perceives it as undefined after the pr ...

How to access the dynamic route's path in Next.js when using Server Components?

Obtaining the dynamic route path in a Next JS server component poses a challenge. This task is simple when working with client components. If you are working on src/app/[id]/page.tsx "use client"; import { usePathname } from "next/navigatio ...

Using brackets around or after an expression in Typescript

Exploring Typescript: Is there a distinction between the two square bracket notations? After running some tests, it appears they function equivalently. Any insights would be appreciated! interface test { a: string; b: string; } const x: test[] = [{a ...

Tips for configuring VS Code to display and check object schemas

npm init -y npm i axios npm i @types/axios --save-dev Why doesn't VS Code 1.62 seem to provide the response object schema when typing code like this: resp = await axios("https://httpstat.us/404"); resp. <C-Space> displays confusing / inappropr ...

Steps for sending a POST request for every file in the given array

I am working on an angular component that contains an array of drag'n'dropped files. My goal is to make a POST request to http://some.url for each file in the array. Here is what I have been attempting: drop.component.ts public drop(event) { ...

Struggling to fix TypeScript error related to Redux createSlice function

Here is the code snippet I am working on: import { Conversation } from "@/types/conversation"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; const initialState: Conversation | null = null; export const conversationSli ...

Can someone guide me on incorporating static methods into a Mongoose model using TypeScript for Mongoose version 5.11?

When using Mongoose 5.10, I implemented static methods in my Mongoose models with the following pattern: import { Schema, Document, Model, Connection } from "mongoose"; import { v4 } from "uuid"; export interface IFoo extends Document ...

Retrieve all the characteristics accessible of a particular course

I am facing a situation where I have the following class structure: class A { id: number propertyA: string constructor(id: number) { this.id = id } } let a = new A(3) console.log(SomeFunction(a)) // expected output = ['id', ' ...

An error occurs when attempting to use object mapping and the rest operator in a return statement due to

I've encountered a type mismatch error in my TypeScript project using Prisma while attempting to return an object with mapped properties in the getPool method. Let's take a look at the code snippet causing the issue: public async getPool({ id, v ...

Guide to setting up react-styleguidist, developing with Create React App, using Typescript, incorporating Material UI, and including

Struggling to configure react-styleguidist (RSG) with Create React App 3 (CRA), Typescript, Material UI, and styled-components. Currently encountering an error: ./node_modules/react-styleguidist/lib/client/rsg-components/ReactExample/ReactExample.js Modul ...