如何在打字稿中键入部分应用的函数?

时间:2020-06-08 07:05:44

标签: typescript partial-application

如何在不使用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 {

过了一会儿,许多尝试理解和使用更高级的概念失败了,我尝试使用一个函数进行相同的操作,如果存在一个参数,该函数可能只返回数字或字符串,并且以相同的方式失败:< / p>

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"),这不是我尝试的方法完成。

是否正在打字稿中做类似的事情?

1 个答案:

答案 0 :(得分:3)

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

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");