gpt4 book ai didi

基于可选参数存在而不使用函数重载的 typescript 函数返回类型

转载 作者:行者123 更新时间:2023-12-04 08:47:06 25 4
gpt4 key购买 nike

Typescript playground
我的目标是根据可选 condition: "CONDITION" 的存在返回不同的类型。范围。我试图在不诉诸重载的情况下做到这一点。

type TYPE_1 = "TYPE_1"
type TYPE_2 = "TYPE_2"

type CONDITION = "CONDITION"

function foo(condition?: CONDITION): TYPE_1 | TYPE_2 {
if (condition) {
return "TYPE_1";
}
else {
return "TYPE_2";
}
}

const shouldBeType_1 = foo("CONDITION"); // ERROR: THIS IS BEING EVALUATED AS UNION TYPE: "TYPE_1" | "TYPE_2"
const shouldBeType_2 = foo(); // ERROR: THIS IS BEING EVALUATED AS UNION TYPE: "TYPE_1" | "TYPE_2"
这很容易通过重载来实现:
/* ########################################### */
/* #### THIS IS EASY TO DO WITH OVERLOADS #### */
/* ########################################### */

function foo_overloaded(): TYPE_2
function foo_overloaded(condition: "CONDITION"): TYPE_1
function foo_overloaded(condition?: "CONDITION"): TYPE_1 | TYPE_2 {
if (condition) {
return "TYPE_1";
}
else {
return "TYPE_2";
}
}

const overloaded_shouldBeType_1 = foo_overloaded("CONDITION"); // SUCCESS: THIS IS TYPE_1
const overloaded_shouldBeType_2 = foo_overloaded(); // SUCCESS: THIS IS TYPE_2
没有重载的正确方法是什么?或者我是否过度复杂化并且重载只是在这种情况下要走的路?
SO上也有这个问题: TypeScript: function return type based on argument, without overloading
它建议应该将接口(interface)用作返回类型的映射,例如:
interface Registry {
A: number,
B: string,
C: boolean
}

function createType<K extends keyof Registry>(type: K, value: Registry[K]): Registry[K] {
return value;
}
但我不能这样做,因为 condition"CONDITION" | undefined .那么如何映射 undefined类型?我也尝试使用条件类型来做到这一点。就像是:
type RETURN_TYPE<T extends undefined | "CONDITION"> = T extends "CONDITION" ? TYPE_1 : TYPE_2;
但这也没有用。

最佳答案

我想说在这种情况下你会使用重载函数,你可以通过以下方式部分解决这个问题:

function foo<T extends CONDITION | undefined>(condition?: T): T extends CONDITION ? TYPE_1 : TYPE_2 {
if (condition) {
//`as any` is intentional here: https://stackoverflow.com/questions/55641731/typescript-conditional-type-complains-type-not-assignable
return "TYPE_1" as any;
} else {
return "TYPE_2" as any;
}
}
有了这个,以下工作正常:
const shouldBeType_1 = foo("CONDITION") // It is TYPE_1;
但是,当您不传递任何参数时,它将不起作用:
const shouldBeType_2 = foo(); // It is TYPE_1 | TYPE_2
当然,如果你直接传递 undefined ,它就可以正常工作:
const shouldBeType_2 = foo(undefined); // It is TYPE_2;

长话短说,现在,解决您的问题的最干净的方法是使用函数重载。

编辑
正如已经指出的那样,如果我为泛型类型添加一个默认参数,这也适用于省略的参数。
function foo<T extends CONDITION | undefined = undefined>(condition?: T): T extends CONDITION ? TYPE_1 : TYPE_2 {
if (condition) {
return "TYPE_1" as any;
} else {
return "TYPE_2" as any;
}
}

// Both work:
const shouldBeType_1 = foo("CONDITION") // It is TYPE_1;
const shouldBeType_2 = foo(); // It is TYPE_2;

关于基于可选参数存在而不使用函数重载的 typescript 函数返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64259852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com