Open In App

How to Implement a Generic Function with a Conditional Return Type ?

Last Updated : 18 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Implementing a generic function with a conditional return type involves creating a function that can accept multiple data types and return different types based on specified conditions. This allows for flexible behavior depending on inputs. The function’s return type may vary dynamically, enhancing its versatility and utility in handling diverse scenarios within a program or system. There are several ways to implement a generic function with conditional return types which are as follows:

Using Conditional Types

In this approach the Conditional types in TypeScript enable dynamic typing based on conditions, allowing the return type of a function to vary depending on the input type or other criteria, enhancing type flexibility and inference.

Example: To demonstrate the function using a conditional type, returning the length of a string input as a number, or false or non-string input adhering to ReturnType<T> constraints.

Javascript
type ReturnType<T> = T extends string ? number : boolean;

function getResult<T>(input: T): ReturnType<T> {
    return typeof input === 'string' ? 
        input.length as ReturnType<T> : false as ReturnType<T>;
}

const result1 = getResult("GeeksforGeeks");
const result2 = getResult(10);

console.log(result1);
console.log(result2);

Output:

13
False

Using Type Switching

Type Switching in TypeScript involves using a switch statement to determine the type of a variable dynamically, enabling conditional behaviour based on types, and facilitating versatile handling of different data types within a function.

Example: In this example, The function `getValue<T>` returns the length of a string input or true for non-strings.

Javascript
function getValue<T>(input: T): T extends string ? number : boolean {
    switch (typeof input) {
        case 'string':
            return (input as unknown as string)
                .length as T extends string ? number : boolean;
        default:
            return input === 0 ? false as T extends string ? number : 
                boolean : true as T extends string ? number : boolean;
    }
}

const result1 = getValue("Geeks");
const result2 = getValue(10);

console.log(result1);
console.log(result2);

Output:

5
true

Using Type Assertion

Type assertion involves explicitly specifying the return type of a function, overriding TypeScript’s inference. It’s a manual approach and requires ensuring type safety.

Example: In this example, we are following the approach mentioned above.

Javascript
function getValue<T>(input: T): 
    T extends string ? number : boolean {
    switch (typeof input) {
        case 'string':
            return (input as unknown as string)
                .length as T extends string ? number : boolean;
        default:
            return (input === 0 ? false : true) as T extends string ? 
                number : boolean;
    }
}

const result = getValue("GeeksforGeeks");

console.log(result);

Output:

13

Using Type Guards:

Using type guards, a generic function checks the type of its input. If it matches a condition, it returns a specific type; otherwise, it returns another type, enabling conditional return types.

Example: In this example The function infers return types based on input types: length of a string for strings, and `false` for non-strings, respecting conditional return types.

JavaScript
function getResult<T>(input: T): T extends string ? number : boolean {
    if (typeof input === 'string') {
        return input.length as T extends string ? number : boolean;
    } else {
        return false as T extends string ? number : boolean;
    }
}

// Test with string input
const result1: number = getResult("hello");

// Test with number input
const result2: boolean = getResult(10);

console.log(result1); 
console.log(result2); 

Output:

5
false


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads