如何允许打字稿通用参数具有默认值

发布于 2025-02-12 17:50:37 字数 943 浏览 2 评论 0 原文

我正在尝试为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&lt;“ ligal”&gt;(); ),我已经阅读了几篇文章,以便尝试并解决。

但是,

  1. 我不想强​​迫人们通过参数。
  2. 我想返回条件类型(不是不受约束的字符串,而不是联合)

我该怎么做?

I am trying to set a default for a generic function in TS. Here is a simplistic example:

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>;
}

It causes the error:

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)

I understand the problem (ex: someone could try getDetail<"large">(); ) and I've read several posts on SO to try and resolve.

However,

  1. I don't want to force people to pass a parameter.
  2. I want to return the conditional type (not unconstrained string, not union)

How can I do something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

oО清风挽发oО 2025-02-19 17:50:38

我会用您的不同值创建一个枚举,然后基于此创建您的功能。当您要求返回作为条件类型时,我还添加了一个接口,因此返回是TypeAfe:

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

I would create a Enum with your different values and then create your function based on that. As you requested the return as a conditional type, i also added an Interface so the return is typesafe:

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());
软的没边 2025-02-19 17:50:37

我会将添加为“小” 作为 size 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>;
}

游乐场

I would add "small" as type for size and I would also add "small" as default for the generic type.

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>;
}

Playground

不念旧人 2025-02-19 17:50:37

最好做到这一点

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

通过功能超载游乐场链接

This is better done with function overloads

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

Playground link

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文