In TypeScript, is it possible to make the result type of a function depend on the input parameter?

I have been experimenting with the coding TypeScript playground and here's what I've come up with so far:

export type Encoding = 'buffer' | 'blob' | 'base64'

export default async function md2docx<E extends Encoding>(
  text: string,
  encoding: E,
): Promise<
  E extends 'blob' ? Blob : E extends 'buffer' ? number : string
> {
  switch (encoding) {
    case 'buffer': return 10 //Buffer.from(text)
    case 'blob': return new Blob([text])
    case 'base64': atob(text)
  }
}

md2docx('foo', 'blob').then(output => {
  output.arrayBuffer
})

I am aiming to specify the encoding type for the function md2docx and ensure the correct type is returned, while also having proper typing in the output variable. Currently, my code is not functioning as intended. If I go with the current setup, I have to manually check if output instanceof Blob, which is something I would prefer to avoid:

export type Encoding = 'buffer' | 'blob' | 'base64'

export default async function md2docx<E extends Encoding>(
  text: string,
  encoding: E,
) {
  switch (encoding) {
    case 'buffer': return 10 //Buffer.from(text)
    case 'blob': return new Blob([text])
    case 'base64': atob(text)
  }
}

md2docx('foo', 'blob').then(output => {
  if (output instanceof Blob) {
    output.arrayBuffer; // .arrayBuffer property exists.
  }
})

Answer №1

It appears this solution is effective...

export type Format = 'data' | 'file' | 'encode'

async function converter(
  data: string,
  format: 'file'
): Promise<File>;
async function converter(
  data: string,
  format: 'data'
): Promise<number>;
async function converter(
  data: string,
  format: 'encode'
): Promise<string>;
async function converter(
  data: string,
  format: Format
) {
  const x: number = 10;
  switch (format) {
    case 'file': return new File([data])
    case 'data': return x
    case 'encode': return btoa(data)
  }
}

export default converter;

converter('foo', 'file').then(result => {
  result.arrayBuffer
})

I modified .data to .arrayBuffer. Furthermore, the TypeScript Playground failed to recognize return 10 as returning a number, so I introduced a constant numeric variable and used that for the return statement instead.

Refer to TypeScript manual on Function Overloads

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

Injecting a service into a base class in Angular, but not in the sub-class, then utilizing the parent service in the sub-

When working with Angular 7 and Typescript, I have a base class that relies on multiple services and has around 40 subclasses. Instead of adding these services to each subclass constructor and passing them to super(), I am looking for a more efficient wa ...

Getting parameter names (or retrieving arguments as an object) within a method decorator in TypeScript: What you need to know

I am currently working on creating a method decorator that logs the method name, its arguments, and result after execution. However, I want to implement a filter that allows me to choose which parameters are logged. Since the number and names of parameter ...

When working with TypeScript, encountering an error involving an array containing an index signature

When attempting to change an object's type to a generic array using the as keyword, I encountered an error. interface TestType { action: TestGeneric<number>[] } type TestGeneric<T> = { [key: string]: T } const func = () => { ...

How can we effectively implement alert notifications for validating image sizes and formats prior to uploading?

code playground : https://codesandbox.io/s/quizzical-lamport-ql5ep I'm encountering an issue with the code provided in the CodeSandbox link. https://i.sstatic.net/xg3aK.png I've attempted to resolve this issue using various methods, but unfortu ...

Utilizing express-session in TypeScript: Incorporating user information into the session

Hey, I'm currently working on implementing express-session and connect-mongodb-session in my TypeScript Express/Node API. My goal is to use express-session to create a cookie for logged-in users and automatically persist that cookie to MongoDB. Howeve ...

Develop a custom data structure by combining different key elements with diverse property values

Within my coding dilemma lies a Union of strings: type Keys = 'a' | 'b' | 'c' My desire is to craft an object type using these union keys, with the flexibility for assigned values in that type. The typical approach involves ...

Tips for correctly passing the appropriate data type using generics in TypeScript

If I have an array of objects with a key called render, which may be an optional function that takes a parameter (unknown type) const objectArray = [{a: 1}, {b: 2, render: renderFunction}, {c: 3, render: anotherFunction}] suppose the second object's ...

Having trouble with updating a Firebase database object using snap.val()

I'm trying to figure out how to update a property within the snap.val() in order to make changes to my Firebase database. function updateListItem(listItem) { var dbRef = firebase.database() .ref() .child('userdb') .child($sco ...

The type 'undefined' cannot be assigned to a different type within the map() function, resulting in a loss of type information

I am facing an issue in my redux toolkit where an action is trying to set some state. Below is the relevant code snippet: interfaces export interface ProposalTag { id: number; name: string; hex: string; color: string; } export interface ProposalS ...

Can you merge two TypeScript objects with identical keys but different values?

These TypeScript objects have identical keys but different properties. My goal is to merge the properties from one object onto the other. interface Stat<T, V> { name: string; description: string; formatValue: (params: { value: V; item: T }) =&g ...

How to use TypeScript to modify button styling with an OnClick() event handler

Learning TypeScript with Existing Code Transition Currently, I am delving into the world of TypeScript and in the process of converting my CoffeeScript code to TypeScript (specifically Lit Web Component). Confusion on Translation Process I'm encount ...

Leveraging imported libraries from a parent class is a common practice in Angular

"angular2": "2.0.0-beta.17", How can I import { Http, Response } from 'angular2/http'; in my Base class and use http in the child classes? Is there a way to achieve this? P.S. I'm open to hacks, workarounds, and unconventional solutions. ...

TypeScript is unable to identify import paths

Currently facing an issue with a specific error in my development environment. I am working with React, TypeScript, and node.js using VSCode on a Mac. I can't pinpoint exactly when this error started occurring. Despite the existence of the file route ...

Is it possible to harness the power of a Typescript array within my HTML while incorporating primeng chips?

My subject line brings up a question: How can I transform the following piece of HTML code? HTML <p-chip label="1 day(s)" styleClass="p-mb-2 p-mr-2 custom-chip"></p-chip> <p-chip label="2 day(s)" styleClass=&qu ...

Tips for utilizing the keyword 'this' within a Promise

Seeking assistance with resolving an issue involving an undefined error when attempting to make an http request within a Promise function. The error occurs due to this.http.post being undefined, indicating that there is an issue with accessing this properl ...

I'm having trouble setting a value for an object with a generic type

I am attempting to set a value for the property of an object with generic typing passed into a function. The structure of the object is not known beforehand, and the function receives the property name dynamically as a string argument. TypeScript is genera ...

Encountering a Typescript issue with the updated Apollo server version within a NestJS application

After upgrading my nestJS application to use version 3.2 of apollo-server-plugin-base, I encountered two TypeScript errors related to a simple nestJS plugin: import { Plugin } from '@nestjs/graphql' import { ApolloServerPlugin, GraphQLRequest ...

Tips for establishing communication between a server-side and client-side component in Next.js

I am facing a challenge in creating an interactive component for language switching on my website and storing the selected language in cookies. The issue arises from the fact that Next.js does not support reactive hooks for server-side components, which ar ...

Tips for customizing the `src/app/layout.tsx` file in Next.js 13

I am looking to customize the layout for my /admin route and its child routes (including /admin/*). How can I modify the main layout only for the /admin/* routes? For example, I want the / and /profile routes to use the layout defined in src/app/layout.ts ...

Using Angular 2 to round a calculated number within HTML

In the HTML code, there is a calculated number associated with Component1. Component1 serves as a tab page within a Bootstrap tab panel. Below is the HTML code with the tab panel: <div id="minimal-tabs" style="padding:75px;padding-top:60 ...