Defining types for functions that retrieve values with a specified default

My method aims to fetch a value asynchronously and return it, providing a default value if the value does not exist.

async get(key: string, def_value?: any): Promise<any> {
   const v = await redisInstance.get(key);

   return v ? v : def_value;
}

Would it be possible to specify proper types for this method instead of using 'any'?

I had the idea to modify the method signature like this:

async get<T>(key: string, def_value?: T): Promise<T> 

This way, the type would be inferred from def_value, but then def_value couldn't be optional. Is there a way to make def_value both optional (undefined) and of type T? Can TypeScript detect if a default value was provided or not? If a default value is provided, infer T from that value; if no default value is provided, prompt for a type, like

get<string[]>("my_key");
?

Answer №1

interface Mapper {
  key: 'value'
}

declare const redisClient: { fetch(data: any): any }

1) with mapping (in case the list of keys is fixed)
async function obtain<K extends keyof Mapper>(dataKey: K, defaultValue?: Mapper[K]): Promise<Mapper[K]> {
  return (await redisClient.fetch(dataKey) as Mapper[K]) ?? defaultValue;
}

obtain('key')
obtain('key', 'value')
// function obtain<"key">(dataKey: "key", defaultValue?: "value" | undefined): Promise<"value">

// 2) using overloading approach:
async function obtainValue<T>(dataField: string, defaultValue: T): Promise<T>;
async function obtainValue<T>(dataField: unknown extends T ? ['must provide a generic'] : string): Promise<T | undefined>;
async function obtainValue<T>(dataField: any, defaultValue?: T): Promise<T | undefined> {
  return (await redisClient.fetch(dataField) as T) ?? defaultValue;
}

obtainValue('key') // Argument of type 'string' is not assignable to parameter of type '["must provide a generic"]'.(2345)
obtainValue<string[]>('key')
obtainValue('key', ['value']) // Promise<string[]>

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

Using Javascript to define cookie values

I'm attempting to use JavaScript to set a cookie that will instruct Google Translate to select the language for the page. I've experimented with setting the cookie based on my browser's cookie selection of a language. <script> $(doc ...

Is it possible to convert JSON to enum using TypeScript?

I have a JSON string that looks like the following. { "type": "A", "desc": "AAA" } or { "type": "B", "desc" "BBB" } etc. How can I utilize an enum in Ty ...

Ways to transfer information among Angular's services and components?

Exploring the Real-Time Binding of Data Between Services and Components. Consider the scenario where isAuthenticated is a public variable within an Authentication service affecting a component's view. How can one subscribe to the changes in the isAut ...

Display the HTML content once the work with AJAX and jQuery has been successfully finished

Below are the codes that I have created to illustrate my question. It's not a complete set of code, just enough to explain my query. The process goes like this: HTML loads -> calls ajax -> gets JSON response -> appends table row with the JSO ...

Execute a script once the AngularJS view has finished loading

Just starting out with AngularJS and I've encountered an issue; I'm populating part of my view with HTML from a variable in my controller: <div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div> Everything works as expected ...

experiencing an excessive amount of re-renders after transferring data to a distinct component

At the moment, I have implemented this logic to display data based on the results of a graphql query, and it is working well: const contacts = () => { const { loading, error, data } = useUsersQuery({ variables: { where: { id: 1 }, ...

Is Python being used to track NBA.com stats?

Does anyone have any advice on how to extract NBA.com "tracking" stats using a python script and display them in a simple table? I'm particularly struggling with this specific section of stats on the site. Accessing stats directly from NBA.com can be ...

Trouble with Fetch in JS and PHP not sending parameters

Having trouble getting a PHP function to accept data from JavaScript, despite the PHP class working elsewhere in the application. The getTopFive() function works fine, but data insertion isn't happening as expected. Below is the code snippet along wit ...

What role does the conditional statement play in the function ExtrudeGeometry.UVGenerator.generateSideWallUV within three.js?

Within three.js's ExtrudeGeometry.UVGenerator.generateSideWallUV function, there is a specific condition being checked: if ( Math.abs( a.y - b.y ) < 0.01 ) { return [ new Vector2( a.x, 1 - a.z ), new Vector2( b.x, ...

HTML5 Canvas Border

Hey Everyone, I've been working on an HTML5 canvas project where I set the canvas width to $(window).width(). Everything was going smoothly until I added a border, which caused a horizontal scroll to appear. Important: I attempted to use the innerWid ...

Looking for guidance on utilizing pushState and handling onpopstate events?

By using ajax, I am able to load specific page content without refreshing the entire page. In order to make the back button functionality work, I utilize pushState and onpopstate as shown below: function get_page(args){ .... $.ajax({ url ...

The unit argument provided for Intl.NumberFormat() is not valid for electrical units such as volts and joules

After attempting to localize my web application, I have run into an issue with Intl.NumberFormat not working properly with electric units such as ampere, ohm, volt, and joule. The documentation provides examples and a list of available units. Despite fol ...

Sliding and repositioning elements using jQuery

My goal is to build a simple slideshow for learning purposes. I want the list items to slide automatically to the left in a continuous loop. I've written some code that makes the slides move, but I'm struggling to set the correct position for ea ...

Reduce the combined character value of the title and excerpt by trimming the excess characters

I am seeking a solution to trim the total character count of a post title and excerpt combined. Currently, I can individually adjust the excerpt through theme settings and the post title using JavaScript. However, due to varying title lengths, the height ...

Importing dynamically into Ionic 2 from locations other than the "node_modules" directory

I've recently reviewed the documentation for ModuleResolution in TypeScript on this page: https://www.typescriptlang.org/docs/handbook/module-resolution.html#node My understanding is that all files I wish to import must reside within the node_modules ...

Attempting to create a TypeScript + React component that can accept multiple types of props, but running into the issue where only the common prop is accessible

I am looking to create a component named Foo that can accept two different sets of props: Foo({a: 'a'}) Foo({a: 'a', b: 'b', c:'c'}) The prop {a: 'a'} is mandatory. These scenarios should be considered i ...

Exploring Next.js Font Styling and Utilizing CSS Variables

I'm attempting to implement the "next" method for adding fonts, but I find the process described quite complex just to preload a font. I experimented with exporting a function to create the font and then using a variable tag to generate a CSS variabl ...

angular http fails to verify authorization header

My backend is set up in Node.js with Express and Sequelize. When I make a request to retrieve all my product types using Postman, everything works fine as shown in this image: postman http request and header However, when I try to make the same request f ...

Debugging TypeScript code in VS Code by stepping into a library function within the Node.js debugger

After developing a TypeScript library and its corresponding testing program, I have implemented source maps for both projects. Utilizing the node.js debugger, I am now faced with an issue. While debugging my TypeScript code in the program is successful, t ...

The form submission feature is malfunctioning due to JavaScript issues

I have forms that allow file uploads (images), and I am trying to restrict the size of those images to 500KB. However, for some reason, the forms are not submitting and I am unsure why. Below is the jQuery code: $('form').on('submit', ...