首页 > 解决方案 > 如何在打字稿中键入部分应用的函数?

问题描述

如何在不使用的情况下正确键入以下函数的返回类型any?它是一个函数,根据一个参数的存在,返回一个字符串或一个函数。

function useFetchResource(resourceType: string, id?: string): string {
    if (id) {
        return `${resourceType}:${id}`; 
    } else {
        // ERROR HERE
        return (innerId: string) => {
            return `${resourceType}:${innerId}`;
        };
    }
}

useFetchResource("products", "10");
const fetchProduct = useFetchResource("products");
// ERROR HERE
fetchProduct("10");

我试过使用重载但没有成功:

function useFetchResource(resourceType: string): ((id: string) => string); // COMPILE ERROR: Incompatible implementation
function useFetchResource(resourceType: string, id?: string): string {

过了一段时间,许多试图理解和使用更高级概念的尝试都失败了,我尝试了一个函数,如果存在一个参数,它可能只返回一个数字或一个字符串,但它以同样的方式失败:

function useFetchResource(resourceType: string): number; // COMPILE ERROR: Incompatible implementation
function useFetchResource(resourceType: string, id?: string): string {
    if (id) {
        return `${resourceType}:${id}`; 
    } else {
        return 1;
    }
}

我也尝试过使用联合类型,string | ((id: string) => string)但它迫使函数的使用者强制转换值以使用它:(fetchProduct as ((id: string) => string))("10"),这不是我试图完成的。

在打字稿中可以做类似的事情吗?

标签: typescriptpartial-application

解决方案


您必须定义函数的重载和实现。

function useFetchResource(resourceType: string): (id: string) => string;
function useFetchResource(resourceType: string, id: string): string;
function useFetchResource(resourceType: string, id?: string): string | ((id: string) => string) {
    if (id) {
        return `${resourceType}:${id}`; 
    } else {
        // ERROR HERE
        return (innerId: string) => {
            return `${resourceType}:${innerId}`;
        };
    }
}

const key = useFetchResource("products", "10");
const fetchFunction = useFetchResource("products");

// No ERROR HERE
fetchFunction("10");

推荐阅读