Return Promise 或 boolean 取决于具有默认值的参数

Return Promise or boolean depending on parameters with a default

我有一些代码可以根据参数 return 布尔值或 Promise。

function setGuid<B extends boolean>(guid: string, shouldValidate?: B): B extends true ? boolean : Promise<boolean>
function setGuid(guid: string, shouldValidate?: boolean): boolean | Promise<boolean> {
    if (shouldValidate){
        return true
    }
    return Promise.resolve(true);
}

此功能有效。如果我调用 setGuid("*", false) 它理解 return 类型将是 Promise<boolean> 同样如果我调用 setGuid("*", true) TypeScript 理解 return 类型将是 boolean.

问题是我不知道如何设置默认的 return 类型,如果没有提供 shouldValidate(可选参数)则为 Promise<boolean> - 我希望 TypeScript 理解 setGuid("*") 将 return Promise<boolean>。目前,如果我不明确提供 false 作为第二个参数,它认为 boolean | Promise<boolean> 正在 returned.

我在调用 setGuid("*") 时遇到的错误是 Property 'then' does not exist on type 'boolean | Promise<boolean>'. Property 'then' does not exist on type 'false'.

非常感谢任何帮助,谢谢!

如果您不将任何内容作为 shouldValidate 传递,那么编译器将无法使用任何内容来推断 B 的类型。因此,它将倾向于默认其约束,即 boolean。正如您所见,B extends true ? boolean : Promise<boolean> 将成为联合体 boolean | Promise<boolean>,因此这种行为很糟糕。

在这种情况下,您可以将 generic parameter default 添加到重载调用签名中,如下所示:

function setGuid<B extends boolean = false>(
  guid: string, 
  shouldValidate?: B
): B extends true ? boolean : Promise<boolean>;

如果编译器无法以其他方式推断 B:

,则将使用此默认值
setGuid("*").then(x => x ? 0 : 1); // no error now

好的,希望对你有帮助;祝你好运!

Playground link to code