如果在打字稿中传递了可选参数,则更改函数 return 类型

Change function return type if optional argument is passed in typescript

我有以下功能:

const lists = {mylist: ["alpha", "beta", "gamme"]};

function foo(listName, element) { 
    if (typeof element !== 'undefined') {
        return !!lists[listName].find(x => x === element);
    }

    return [lists[listName], () => refreshLists()];
}

foo('mylist'); // returns [string[], () => any]
foo('mylist', 'alpha') // returns boolean

如您所见,该函数有 2 种不同的 return 类型,具体取决于是否设置了参数 element。我怎样才能用 typescript 正确地表示它,以便编辑器根据传递的参数选择正确的 return 类型?

我目前的解决方案是这样的,但编辑器无法识别:

export type FnReturnType<T> = [T] extends [undefined] ? [string[], () => any] : boolean;

function foo<T extends string | undefined>(listName: string, element: T): FnReturnType<T> { 
    if (typeof element !== 'undefined') {
        return !!lists[listName].find(x => x === element);
    }

    return [lists[listName], () => refreshLists()];
}

如果 typeof element !== undefined 否则如何创建 return 布尔值的条件类型,否则 [string[], () => any]

使用function overloading.

您为不同的参数类型和 return 类型编写了两个单独的重载签名,然后编写将 return 正确值的函数实现。

function foo(listName: string): [string[], () => any]; // overload signature #1
function foo(listName: string, element: string): boolean; // overload signature #2
function foo(listName: string, element?: string): boolean | [string[], () => any] { // function implementation
  if (typeof element !== 'undefined') {
      return !!lists[listName].find(x => x === element);
  } 
  
  return [lists[listName], () => refreshLists()];
}

勾选playground