如何在打字稿中输入部分应用的功能?

How to type a partially applied function in typescript?

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

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 {

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

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"),这不是我想要的试图完成。

在 typescript 中可以做类似的事情吗?

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

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