如何允许Typescript的泛型参数有default



我试图在TS中设置一个通用函数的默认值,下面是一个简单的例子:

type Size = "small" | "medium" | "large";
type Detail<S extends Size> = S extends "small" ? "noDetail" : S extends "medium" ? "partialDetail" : "fullDetail"
function getDetail<S extends Size>(size:S = "small"):Detail<S>{
if(size === "small")
return "noDetail" as Detail<S>;
if(size === "medium")
return "partialDetail" as Detail<S>
return "fullDetail" as Detail<S>;
}

导致错误:

Type '"small"' is not assignable to type 'S'.
'"small"' is assignable to the constraint of type 'S', but 'S' could be instantiated with a different subtype of constraint 'Size'.ts(2322)

我理解这个问题(例如:有人可以尝试getDetail<"large">();),我已经阅读了一些关于SO的帖子来尝试解决。

然而,

  1. 我不想强迫人们传递一个参数。
  2. 我想返回条件类型(不是无约束字符串,不是联合)

我怎样才能做到这样呢?

最好使用函数重载

function getDetail(): Detail<"small">;
function getDetail<T extends Size>(size: T): Detail<T>;
function getDetail(size: Size = "small"): Detail<Size>{
if(size === "small")
return "noDetail";
if(size === "medium")
return "partialDetail";
return "fullDetail";
}

操场上联系

我将"small"添加为size的类型,我还将"small"添加为通用类型的默认值。

function getDetail<S extends Size = "small">(size: S | "small" = "small"):Detail<S>{
if(size === "small")
return "noDetail" as Detail<S>;
if(size === "medium")
return "partialDetail" as Detail<S>
return "fullDetail" as Detail<S>;
}

游乐场

我会创建一个具有不同值的Enum,然后基于此创建您的函数。当您请求返回作为条件类型时,我还添加了一个接口,因此返回是类型安全的:

enum Size {
"small",
"medium",
"large"
}
interface Detail<Size> {
model: string
}
function getDetail(size:Size = Size.small){
return {
model: Size[size]
} as Detail<typeof size>;
}
console.log(getDetail(Size.medium));
console.log(getDetail());

最新更新